• Do not use Discord to host any images you post, these links expire quickly! You can learn how to add images to your posts here.
  • Eevee Expo's webhost has been having technical issues since Nov. 20th and you might be unable to connect to our site. Staff are also facing issues connecting, so please send a DM to Cat on-site or through Discord directly for faster service!
Resource icon

Resource [v20\v21] Secret Bases Remade 3.0.0

CarlosPR

Novice
Member
Joined
Mar 6, 2022
Posts
49
I'm getting this error when I compile my game. I'm upgrading my game from v20.1 and downloaded the v21 update but after checking all changes and adding all the stuff I get this error message.
 

Attachments

  • Screenshot 2023-11-15 141029.png
    Screenshot 2023-11-15 141029.png
    118.3 KB · Views: 50

CarlosPR

Novice
Member
Joined
Mar 6, 2022
Posts
49
I'm getting this error when I compile my game. I'm upgrading my game from v20.1 and downloaded the v21 update but after checking all changes and adding all the stuff I get this error message.
I don't know what I did, but is working now.
 

SalyaDarken

Breeder?
Member
Joined
Jan 3, 2022
Posts
52
I'm use 21.1 and I can't get this to work. Plus I would love to make bases like how Pokemon insurgence did. Is there any way to do it? Since I use different tilesets per base.
 
Last edited:

Vendily

Elite Trainer
Member
I'm use 21.1 and I can't get this to work. Plus I would love to make bases like how Pokemon insurgence did. Is there any way to do it? Since I use different tilesets per base.
Can't get this to work is rather vague.
Did you define a base in the PBS file, but it's not showing up? If so, you may need to compile the game.
Is it erroring? you should post it, so I can debug it.

The script doesn't allow for different tilesets per base, as decorations are on the same tileset too. I am not familiar with how Insurgence did their bases.
 

SalyaDarken

Breeder?
Member
Joined
Jan 3, 2022
Posts
52
I did but the only error I get is the mart one. Let me get the error:

[2024-02-20 11:54:45 -0600]
[Pokémon Essentials version 21.1]
[v21.1 Hotfixes 1.0.7]

Script error in event 29 (coords 26,42), map 103 (Secret Base - Forest)
Exception: NameError
Message: undefined local variable or method `stock' for #<Interpreter @event_id: 29>

***Full script:
pbSecretBaseMart(stock, speech = nil,
cansell = false)

Backtrace:
(eval):1:in `execute_script'
Interpreter:138:in `eval'
Interpreter:138:in `execute_script'
Interpreter_Commands:1177:in `command_355'
Interpreter_Commands:116:in `execute_command'
Interpreter:130:in `block in update'
Interpreter:86:in `loop'
Interpreter:86:in `update'
Scene_Map:167:in `block in update'
Scene_Map:166:in `loop'
 

Vendily

Elite Trainer
Member
I did but the only error I get is the mart one. Let me get the error:

[2024-02-20 11:54:45 -0600]
[Pokémon Essentials version 21.1]
[v21.1 Hotfixes 1.0.7]

Script error in event 29 (coords 26,42), map 103 (Secret Base - Forest)
Exception: NameError
Message: undefined local variable or method `stock' for #<Interpreter @event_id: 29>

***Full script:
pbSecretBaseMart(stock, speech = nil,
cansell = false)

Backtrace:
(eval):1:in `execute_script'
Interpreter:138:in `eval'
Interpreter:138:in `execute_script'
Interpreter_Commands:1177:in `command_355'
Interpreter_Commands:116:in `execute_command'
Interpreter:130:in `block in update'
Interpreter:86:in `loop'
Interpreter:86:in `update'
Scene_Map:167:in `block in update'
Scene_Map:166:in `loop'
you don't seem to have passed a stock to the store. you can use it in a similar way to pbPokemonMart, an array of decoration symbols.
 

Hiyouri

Novice
Member
Joined
Aug 13, 2024
Posts
17
After some trial and error, I have managed to add buyable secret bases to the code. A nice way to add something like the villa from Platinum but with the benefits of the secret bases of customising it at one's liking.
View attachment 20438
is it possible to see the lines of code you made for the purchasing system?
 

LinKazamine

Champion
Member
Joined
May 24, 2023
Posts
683
I had to edit some files, but I think I didn't forget any changes. As a note, [001] New GameData/002_SecretBase was commented out completelly and [001] New GameData/005_Compiler_Changes had part of it commented so I could have the edits in another file without they conflicting. [002] Secret Base Classes/005_Base_Creation_interaction_Exterior didn't need that so you can copy the edited code for that in another file without touching the original one (make sure the edited code appears after the original one when ordered by name).

In [001] New GameData/002_SecretBase I have that:
Ruby:
Expand Collapse Copy
module GameData
  class SecretBase
    attr_reader :id
    attr_reader :map_template
    attr_reader :location
    attr_reader :price
    attr_reader :sell_price

    DATA = {}
    DATA_FILENAME = "secret_bases.dat"

    extend ClassMethodsSymbols
    include InstanceMethods

    SCHEMA = {
      "MapTemplate"  => [:map_template, "e", :SecretBaseTemplate],
      "Location"     => [:location, "vuu"],
      "Price"        => [:price, "u"],
      "SellPrice"    => [:sell_price,  "u"]
    }

    def initialize(hash)
      @id               = hash[:id]
      @map_template     = hash[:map_template]
      @location         = hash[:location]
      @price            = hash[:price]       || 0
      @sell_price       = hash[:sell_price]  || (@price / 2)
    end
  end
end

In [001] New GameData/005_Compiler_Changes change lines 18 to 63 (from def compile_secret_bases to the end before def compile_secret_base_decorations):
Ruby:
Expand Collapse Copy
  def compile_secret_bases(path = "PBS/secret_bases.txt")
    compile_pbs_file_message_start(path)
    GameData::SecretBase::DATA.clear
    # Read from PBS file
    File.open(path, "rb") { |f|
      FileLineData.file = path   # For error reporting
      # Read a whole section's lines at once, then run through this code.
      # contents is a hash containing all the XXX=YYY lines in that section, where
      # the keys are the XXX and the values are the YYY (as unprocessed strings).
      schema = GameData::SecretBase::SCHEMA
      idx = 0
      pbEachFileSection(f) { |contents, base_id|
        echo "." if idx % 50 == 0
        idx += 1
        Graphics.update if idx % 250 == 0
        contents["InternalName"] = base_id
        # Go through schema hash of compilable data and compile this section
        schema.each_key do |key|
          FileLineData.setSection(base_id, key, contents[key])   # For error reporting
          # Skip empty properties, or raise an error if a required property is
          # empty
          if contents[key].nil?
            if ["MapTemplate","Location","Price"].include?(key)
              raise _INTL("The entry {1} is required in {2} section {3}.", key, path, base_id)
            end
            next
          end
          # Compile value for key
          value = pbGetCsvRecord(contents[key], key, schema[key])
          contents[key] = value
      
        end
        # Construct type hash
        base_hash = {
          :id            => contents["InternalName"].to_sym,
          :map_template  => contents["MapTemplate"],
          :location      => contents["Location"],
          :price         => contents["Price"],
          :sell_price    => contents["SellPrice"]
        }
        # Add type's data to records
        GameData::SecretBase.register(base_hash)
      }
    }
    # Save all data
    GameData::SecretBase.save
    process_pbs_file_message_end
  end

In [002] Secret Base Classes/005_Base_Creation_Interaction_Exterior modify lines 108 to 206 (from def pbNewSecretBase to the end before the EventHandlers) or simply copy this to a new file (I also have the EventHandlers that appear after it in that file so if they doesn't seem to work maybe you have to copy them as well):
Ruby:
Expand Collapse Copy
# This is the method for the talk to base.
def pbNewSecretBase(base_id)
  # no prompt if this is an open base.
  return if SecretBaseMethods.is_active_secret_base?(base_id)
  move = SecretBaseSettings::SECRET_BASE_MOVE_NEEDED
  movefinder = $player.get_pokemon_with_move(move)
  base_data = GameData::SecretBase.get(base_id)
  template_data = GameData::SecretBaseTemplate.get(base_data.map_template)
  messages_anim = SecretBaseSettings::SECRET_BASE_MESSAGES_ANIM[template_data.type]
  if (!$DEBUG && !movefinder)
    # No mon that can use the Secret Base Move, abort.
    pbMessage(_INTL(messages_anim[0]))
    return
  end
  player_base = $PokemonGlobal.secret_base_list[0]
  moved_bases = false
  if player_base.id && player_base.id != base_id
    # semi-redundant check, but if the player has a base at all (id is not nil), and it's not this one.
    map_name = pbGetMapNameFromId(GameData::SecretBase.get(player_base.id).location[0])
    pbMessage(_INTL("You may only make one Secret Base.\\1"))
    if pbConfirmMessage(_INTL("Would you like to move from the Secret Base near {1}?",map_name))
      pbMessage(_INTL("All decorations and furniture in your Secret Base will be returned to your PC.\\1"))
      if SecretBaseSettings::SECRET_BASE_SPECIAL.include?(GameData::SecretBase.get(player_base.id).type)
        sellPrice = GameData::SecretBase.get(player_base.id).sell_price
        pbMessage(_INTL("You will receive $ {1} for selling this Secret Base.\\1", sellPrice))
      end
      if pbConfirmMessage(_INTL("Is that okay?"))
        if SecretBaseSettings::SECRET_BASE_SPECIAL.include?(GameData::SecretBase.get(player_base.id).type)
          $player.money += sellPrice
        end
        # Pack up the base.
        pbFadeOutIn {
          player_base.remove_decorations((0...SecretBaseSettings::SECRET_BASE_MAX_DECORATIONS).to_a)
          $secret_bag.unplace_all
          player_base.id = nil
        }
        pbMessage(_INTL("Moving completed.\\1"))
        $stats.moved_secret_base_count+=1
        moved_bases = true
      else
        return
      end
    else
      return
    end
  end
  if !moved_bases
    pbMessage(sprintf("%s\\1",_INTL(messages_anim[0])))
  end
  # Now check for the base type.
  if SecretBaseSettings::SECRET_BASE_SPECIAL.include?(template_data.type)
      _, x, y = pbFacingTile
      spriteset = $scene.spriteset($game_map.map_id)
      sprite = spriteset&.addUserAnimation(messages_anim[2], x, y, true, 1)
      SecretBaseMethods.animate_base_opening(base_id, sprite,messages_anim[2],messages_anim[3])
      pbMessage(_INTL(messages_anim[1]))
      pbSEPlay("Door Exit", 80, 100)
      dx,dy = template_data.door_location
      pbFadeOutIn(99999){
        $game_temp.player_transferring   = true
        $game_temp.transition_processing = true
        $game_temp.player_new_map_id    = SecretBaseSettings::SECRET_BASE_MAP
        $game_temp.player_new_x         = dx
        $game_temp.player_new_y         = dy-1
        $game_temp.player_new_direction = 8
        $scene.transfer_player
      }
      move_route=[]
      template_data.preview_steps.times do
        move_route.push(PBMoveRoute::Up)
      end
      pbMoveRoute($game_player,move_route)
      loop do
        Graphics.update
        Input.update
        pbUpdateSceneMap
        break unless $game_player.move_route_forcing
      end
      price = base_data.price
      if !pbConfirmMessage(_INTL("\\GWant to make your Secret Base here?\nIt costs $ {1}.",price.to_s_formatted))
        pbFadeOutIn(99999){
          $game_temp.player_transferring   = true
          $game_temp.transition_processing = true
          $game_temp.player_new_map_id    = base_data.location[0]
          $game_temp.player_new_x         = base_data.location[1]
          $game_temp.player_new_y         = base_data.location[2]+1
          $game_temp.player_new_direction = 2
          $scene.transfer_player
        }
      else
        if $player.money < price
          pbMessage(_INTL("You don't have enough money."))
          pbFadeOutIn(99999){
            $game_temp.player_transferring   = true
            $game_temp.transition_processing = true
            $game_temp.player_new_map_id    = base_data.location[0]
            $game_temp.player_new_x         = base_data.location[1]
            $game_temp.player_new_y         = base_data.location[2]+1
            $game_temp.player_new_direction = 2
            $scene.transfer_player
          }
        else
          $player.money -= price
          px,py = template_data.pc_location
          pbFadeOutIn(99999){
            $PokemonMap.current_base_id = base_id
            player_base.id = base_id
            $game_temp.player_transferring   = true
            $game_temp.transition_processing = true
            $game_temp.player_new_map_id    = SecretBaseSettings::SECRET_BASE_MAP
            $game_temp.player_new_x         = px
            $game_temp.player_new_y         = py+1
            $game_temp.player_new_direction = 8
            $scene.transfer_player
          }
        end
      end
  else
    # Now we ask to use the Secret Base Move.
    if pbConfirmMessage(_INTL("Would you like to use the {1}?",GameData::Move.get(move).name))
      speciesname = (movefinder) ? movefinder.name : $player.name
      pbMessage(_INTL("{1} used {2}!", speciesname, GameData::Move.get(move).name))
      pbHiddenMoveAnimation(movefinder)
      _, x, y = pbFacingTile
      spriteset = $scene.spriteset($game_map.map_id)
      sprite = spriteset&.addUserAnimation(messages_anim[2], x, y, true, 1)
      SecretBaseMethods.animate_base_opening(base_id, sprite,messages_anim[2],messages_anim[3])
      pbMessage(_INTL(messages_anim[1]))
      pbSEPlay("Door Exit", 80, 100)
      dx,dy = template_data.door_location
      pbFadeOutIn(99999){
        $game_temp.player_transferring   = true
        $game_temp.transition_processing = true
        $game_temp.player_new_map_id    = SecretBaseSettings::SECRET_BASE_MAP
        $game_temp.player_new_x         = dx
        $game_temp.player_new_y         = dy-1
        $game_temp.player_new_direction = 8
        $scene.transfer_player
      }
      move_route=[]
      template_data.preview_steps.times do
        move_route.push(PBMoveRoute::Up)
      end
      pbMoveRoute($game_player,move_route)
      loop do
        Graphics.update
        Input.update
        pbUpdateSceneMap
        break unless $game_player.move_route_forcing
      end
      if !pbConfirmMessage(_INTL("Want to make your Secret Base here?"))
        pbFadeOutIn(99999){
          $game_temp.player_transferring   = true
          $game_temp.transition_processing = true
          $game_temp.player_new_map_id    = base_data.location[0]
          $game_temp.player_new_x         = base_data.location[1]
          $game_temp.player_new_y         = base_data.location[2]+1
          $game_temp.player_new_direction = 2
          $scene.transfer_player
        }
      else
        px,py = template_data.pc_location
        pbFadeOutIn(99999){
          $PokemonMap.current_base_id = base_id
          player_base.id = base_id
          $game_temp.player_transferring   = true
          $game_temp.transition_processing = true
          $game_temp.player_new_map_id    = SecretBaseSettings::SECRET_BASE_MAP
          $game_temp.player_new_x         = px
          $game_temp.player_new_y         = py+1
          $game_temp.player_new_direction = 8
          $scene.transfer_player
        }
      end
    end
  end
end

Now, for this all to work you have to add this in the configuration file:
Ruby:
Expand Collapse Copy
  # List of secret base types that don't use a pokemon move.
  SECRET_BASE_SPECIAL = [:house]

And modify the SECRET_BASE_MESSAGES_ANIM to this (it adds a special message for houses but you can have multiple types of selling secret bases with a different message each as long as you have those types registered on the SECRET_BASE_SPECIAL):
Ruby:
Expand Collapse Copy
  # Messages and animation IDs for the secret entrances
  # the type of entrance set for the template in GameData::SecretBaseTemplate is used here
  #  to determine the messages and the animation when opening it.
  # :type => ["On Interact", "On Opening", Animation ID, Frame in Animation to Appear]
  SECRET_BASE_MESSAGES_ANIM={
                    :cave=>[_INTL("There's a small indent in the wall."),
                            _INTL("Discovered a small cavern!"),
                            8,5],
                    :vines=>[_INTL("If some vines drop down, this tree can be climbed."),
                             _INTL("A thick vine dropped down!"),
                             9,-1],
                    :shrub=>[_INTL("If this clump of grass can be moved, it might be possible to go inside."),
                             _INTL("Discovered a small entrance!"),
                             10,-1],
                    :house=>[_INTL("There's a sell sign in the door."),
                             _INTL("You can purchase this Secret Base!"),
                             11,-1]
                   }

With those changes, you can now add a price and sell price (written as "Price" and "SellPrice") in the secret_bases.txt. You can add those on any secret base but it will only be used on those that use the house (or any type you define in the SECRET_BASE_SPECIAL) template so don't forget to register these templates on the plugin.
 

Hiyouri

Novice
Member
Joined
Aug 13, 2024
Posts
17
I think I did the installation correctly but I have this error:

Exception `NoMethodError' at [Secret Bases Remade] 004_Map_Creation_Base_Sprites.rb:12 - undefined method `is_active_secret_base?' for SecretBaseMethods:Module
 

LinKazamine

Champion
Member
Joined
May 24, 2023
Posts
683
Have you deleted everything in [002] Secret Base Classes/005_Base_Creation_Interaction_Exterior? Because the method mentioned in the error is defined in that file and I did not add that to the code I shared there because I did not edit that.
 

Hiyouri

Novice
Member
Joined
Aug 13, 2024
Posts
17
Have you deleted everything in [002] Secret Base Classes/005_Base_Creation_Interaction_Exterior? Because the method mentioned in the error is defined in that file and I did not add that to the code I shared there because I did not edit that.
I got it! I had installed it wrong... but now I have this error and this happens when I enter the house:
Exception `NameError' at [Secret Bases Remade] 005_Base_Creation_Interaction_Exterior.rb:180 - uninitialized constant PBMoveRoute::Up

my script look like that:
Ruby:
Expand Collapse Copy
module SecretBaseMethods
  # @return [Boolean] the if this base has an active id
  def self.is_active_secret_base?(base_id)
    return false unless base_id
    return $PokemonGlobal.secret_base_list.any? {|base| base.id == base_id}
  end
 
  # @return [SecretBase, nil] the active base with this id
  def self.get_base_from_id(base_id)
    return nil unless base_id
    return $PokemonGlobal.secret_base_list.find {|base| base.id == base_id}
  end
 
  # @return [Integer, nil] the index active base with this id
  def self.get_base_index_from_id(base_id)
    return nil unless base_id
    return $PokemonGlobal.secret_base_list.find_index {|base| base.id == base_id}
  end
 
  # @return [Integer, nil] the index active base with this id
  def self.get_base_index_with_owner(base_owner)
    return $PokemonGlobal.secret_base_list.find_index {|base| base.same_owner?(base_owner)}
  end
 
  def self.is_player_base?(base_id)
    return false unless base_id
    return $PokemonGlobal.secret_base_list[0].id == base_id
  end
 
  def self.get_all_inactive_base_ids
    base_ids = []
    GameData::SecretBase.each do |base_id|
      next if is_active_secret_base?(base_id)
      base_ids.push(base_id)
    end
    return base_ids
  end
 
  def self.get_all_active_bases(exclude_ids=nil)
    exclude_ids = [] if !exclude_ids
    return $PokemonGlobal.secret_base_list.select{|base| base.id && !exclude_ids.include?(base.id)}
  end
 
  def self.animate_base_opening(base_id, sprite, type_anim_id, appear_frame = -1)
    animation = $data_animations[type_anim_id]
    fr = 20
    if animation.name[/\[\s*(\d+?)\s*\]\s*$/]
      fr = $~[1].to_i
    end
    animation_time_per_frame = 1.0 / fr
    appear_time = nil
    if appear_frame > 0
      appear_time = appear_frame * animation_time_per_frame
    end
    anim_length =  animation.frame_max * animation_time_per_frame
    shown_base = false
    # set so that it will appear during the animation
    pbWait(anim_length) do |duration|
      next if appear_time.nil? || shown_base
      if appear_time >= duration
        $PokemonMap.current_base_id = base_id
        shown_base = true
      end
    end
    # just in case?
    until sprite.disposed?
      Graphics.update
      Input.update
      pbUpdateSceneMap
    end
    $PokemonMap.current_base_id = base_id
  end
end

def pbGetPlayerBaseLocation(mapname=-1,mapid=-1)
  player_base = $PokemonGlobal.secret_base_list[0]
  if player_base.id.nil?
    location = -1
  else
    location = GameData::SecretBase.get(player_base.id).location[0]
  end
  name = (location > 0) ? pbGetMapNameFromId(location) : ""
  pbSet(mapid,location) if mapid>0
  pbSet(mapname,name) if mapname>0
  return [name, location]
end

# This method is the player touch warp stuff
def pbSecretBase(base_id)
  # No warps if the player isn't entering facing up
  return if $game_player.direction != 8
  # No warps if the base is closed
  return if !SecretBaseMethods.is_active_secret_base?(base_id)
  base_data = GameData::SecretBase.get(base_id)
  template_data = GameData::SecretBaseTemplate.get(base_data.map_template)
  dx,dy = template_data.door_location
  # set current_base_id so secret base setup can proceed.
  pbFadeOutIn(99999){
    $PokemonMap.current_base_id = base_id
    $game_temp.player_transferring   = true
    $game_temp.transition_processing = true
    $game_temp.player_new_map_id    = SecretBaseSettings::SECRET_BASE_MAP
    $game_temp.player_new_x         = dx
    $game_temp.player_new_y         = dy-1
    $game_temp.player_new_direction = 8
    $scene.transfer_player
  }
end

# This is the method for the talk to base.
def pbNewSecretBase(base_id)
  # no prompt if this is an open base.
  return if SecretBaseMethods.is_active_secret_base?(base_id)
  move = SecretBaseSettings::SECRET_BASE_MOVE_NEEDED
  movefinder = $player.get_pokemon_with_move(move)
  base_data = GameData::SecretBase.get(base_id)
  template_data = GameData::SecretBaseTemplate.get(base_data.map_template)
  messages_anim = SecretBaseSettings::SECRET_BASE_MESSAGES_ANIM[template_data.type]
  if (!$DEBUG && !movefinder)
    # No mon that can use the Secret Base Move, abort.
    pbMessage(_INTL(messages_anim[0]))
    return
  end
  player_base = $PokemonGlobal.secret_base_list[0]
  moved_bases = false
  if player_base.id && player_base.id != base_id
    # semi-redundant check, but if the player has a base at all (id is not nil), and it's not this one.
    map_name = pbGetMapNameFromId(GameData::SecretBase.get(player_base.id).location[0])
    pbMessage(_INTL("You may only make one Secret Base.\\1"))
    if pbConfirmMessage(_INTL("Would you like to move from the Secret Base near {1}?",map_name))
      pbMessage(_INTL("All decorations and furniture in your Secret Base will be returned to your PC.\\1"))
      if SecretBaseSettings::SECRET_BASE_SPECIAL.include?(GameData::SecretBase.get(player_base.id).type)
        sellPrice = GameData::SecretBase.get(player_base.id).sell_price
        pbMessage(_INTL("You will receive $ {1} for selling this Secret Base.\\1", sellPrice))
      end
      if pbConfirmMessage(_INTL("Is that okay?"))
        if SecretBaseSettings::SECRET_BASE_SPECIAL.include?(GameData::SecretBase.get(player_base.id).type)
          $player.money += sellPrice
        end
        # Pack up the base.
        pbFadeOutIn {
          player_base.remove_decorations((0...SecretBaseSettings::SECRET_BASE_MAX_DECORATIONS).to_a)
          $secret_bag.unplace_all
          player_base.id = nil
        }
        pbMessage(_INTL("Moving completed.\\1"))
        $stats.moved_secret_base_count+=1
        moved_bases = true
      else
        return
      end
    else
      return
    end
  end
  if !moved_bases
    pbMessage(sprintf("%s\\1",_INTL(messages_anim[0])))
  end
  # Now check for the base type.
  if SecretBaseSettings::SECRET_BASE_SPECIAL.include?(template_data.type)
      _, x, y = pbFacingTile
      spriteset = $scene.spriteset($game_map.map_id)
      sprite = spriteset&.addUserAnimation(messages_anim[2], x, y, true, 1)
      SecretBaseMethods.animate_base_opening(base_id, sprite,messages_anim[2],messages_anim[3])
      pbMessage(_INTL(messages_anim[1]))
      pbSEPlay("Door Exit", 80, 100)
      dx,dy = template_data.door_location
      pbFadeOutIn(99999){
        $game_temp.player_transferring   = true
        $game_temp.transition_processing = true
        $game_temp.player_new_map_id    = SecretBaseSettings::SECRET_BASE_MAP
        $game_temp.player_new_x         = dx
        $game_temp.player_new_y         = dy-1
        $game_temp.player_new_direction = 8
        $scene.transfer_player
      }
      move_route=[]
      template_data.preview_steps.times do
        move_route.push(PBMoveRoute::Up)
      end
      pbMoveRoute($game_player,move_route)
      loop do
        Graphics.update
        Input.update
        pbUpdateSceneMap
        break unless $game_player.move_route_forcing
      end
      price = base_data.price
      if !pbConfirmMessage(_INTL("\\GWant to make your Secret Base here?\nIt costs $ {1}.",price.to_s_formatted))
        pbFadeOutIn(99999){
          $game_temp.player_transferring   = true
          $game_temp.transition_processing = true
          $game_temp.player_new_map_id    = base_data.location[0]
          $game_temp.player_new_x         = base_data.location[1]
          $game_temp.player_new_y         = base_data.location[2]+1
          $game_temp.player_new_direction = 2
          $scene.transfer_player
        }
      else
        if $player.money < price
          pbMessage(_INTL("You don't have enough money."))
          pbFadeOutIn(99999){
            $game_temp.player_transferring   = true
            $game_temp.transition_processing = true
            $game_temp.player_new_map_id    = base_data.location[0]
            $game_temp.player_new_x         = base_data.location[1]
            $game_temp.player_new_y         = base_data.location[2]+1
            $game_temp.player_new_direction = 2
            $scene.transfer_player
          }
        else
          $player.money -= price
          px,py = template_data.pc_location
          pbFadeOutIn(99999){
            $PokemonMap.current_base_id = base_id
            player_base.id = base_id
            $game_temp.player_transferring   = true
            $game_temp.transition_processing = true
            $game_temp.player_new_map_id    = SecretBaseSettings::SECRET_BASE_MAP
            $game_temp.player_new_x         = px
            $game_temp.player_new_y         = py+1
            $game_temp.player_new_direction = 8
            $scene.transfer_player
          }
        end
      end
  else
    # Now we ask to use the Secret Base Move.
    if pbConfirmMessage(_INTL("Would you like to use the {1}?",GameData::Move.get(move).name))
      speciesname = (movefinder) ? movefinder.name : $player.name
      pbMessage(_INTL("{1} used {2}!", speciesname, GameData::Move.get(move).name))
      pbHiddenMoveAnimation(movefinder)
      _, x, y = pbFacingTile
      spriteset = $scene.spriteset($game_map.map_id)
      sprite = spriteset&.addUserAnimation(messages_anim[2], x, y, true, 1)
      SecretBaseMethods.animate_base_opening(base_id, sprite,messages_anim[2],messages_anim[3])
      pbMessage(_INTL(messages_anim[1]))
      pbSEPlay("Door Exit", 80, 100)
      dx,dy = template_data.door_location
      pbFadeOutIn(99999){
        $game_temp.player_transferring   = true
        $game_temp.transition_processing = true
        $game_temp.player_new_map_id    = SecretBaseSettings::SECRET_BASE_MAP
        $game_temp.player_new_x         = dx
        $game_temp.player_new_y         = dy-1
        $game_temp.player_new_direction = 8
        $scene.transfer_player
      }
      move_route=[]
      template_data.preview_steps.times do
        move_route.push(PBMoveRoute::Up)
      end
      pbMoveRoute($game_player,move_route)
      loop do
        Graphics.update
        Input.update
        pbUpdateSceneMap
        break unless $game_player.move_route_forcing
      end
      if !pbConfirmMessage(_INTL("Want to make your Secret Base here?"))
        pbFadeOutIn(99999){
          $game_temp.player_transferring   = true
          $game_temp.transition_processing = true
          $game_temp.player_new_map_id    = base_data.location[0]
          $game_temp.player_new_x         = base_data.location[1]
          $game_temp.player_new_y         = base_data.location[2]+1
          $game_temp.player_new_direction = 2
          $scene.transfer_player
        }
      else
        px,py = template_data.pc_location
        pbFadeOutIn(99999){
          $PokemonMap.current_base_id = base_id
          player_base.id = base_id
          $game_temp.player_transferring   = true
          $game_temp.transition_processing = true
          $game_temp.player_new_map_id    = SecretBaseSettings::SECRET_BASE_MAP
          $game_temp.player_new_x         = px
          $game_temp.player_new_y         = py+1
          $game_temp.player_new_direction = 8
          $scene.transfer_player
        }
      end
    end
  end
end

EventHandlers.add(:on_player_interact, :secret_base_event,
  proc {
    next if $game_player.direction!=8 # must face up
    facingEvent = $game_player.pbFacingEvent
    if facingEvent && facingEvent.name[/SecretBase\((\w+)\)/]
      pbNewSecretBase($~[1].to_sym)
    end
  }
)

HiddenMoveHandlers::CanUseMove.add(SecretBaseSettings::SECRET_BASE_MOVE_NEEDED,
  proc { |move, pkmn, showmsg|
    if $game_player.direction!=8
      pbMessage(_INTL("You can't use that here.")) if showmsg
      next false
    end
    facingEvent = $game_player.pbFacingEvent
    if !facingEvent || !facingEvent.name[/SecretBase\(\w+\)/]
      pbMessage(_INTL("You can't use that here.")) if showmsg
      next false
    end
    next true
  }
)

HiddenMoveHandlers::UseMove.add(SecretBaseSettings::SECRET_BASE_MOVE_NEEDED,
  proc { |move, pokemon|
    facingEvent = $game_player.pbFacingEvent
    if facingEvent && facingEvent.name[/SecretBase\((\w+)\)/]
      pbNewSecretBase($~[1].to_sym)
    end
  }
)
 
Last edited:

LinKazamine

Champion
Member
Joined
May 24, 2023
Posts
683
Ah, sorry, just saw this. The edits are on version 2.2.1 of the plugin, so some things have changed since (like the move route commands that changed between v20.1 and v21+ of pokemon essentials) but you should be able to replicate the changes I did for this.

Most of the code for the pbNewSecretBase (in Base Creation Interaction Exterior) is the original one so copy that (or undo the changes on it). Then you have to copy the conditionals that use if SecretBaseSettings::SECRET_BASE_SPECIAL.include?(GameData::SecretBase.get(player_base.id).type) when closing a secret base (they are before a line with # Now check for the base type. and are used to give the player some money for selling the base).

The code in the conditional after the # Now check for the base type. is for creating the base and is duplicated. The part after the else of the condition is the original code of the plugin so keep it that way. The part between the if and else is where the code for buying is done. Copy the original code for creating the base and add the edits of the messages and the checks on whether the player can keep the secret base or not.

If you don't know how to do it, I'll download the newest version (if I don't have it already) and post my try with the changes.
 

Hiyouri

Novice
Member
Joined
Aug 13, 2024
Posts
17
Ah, sorry, just saw this. The edits are on version 2.2.1 of the plugin, so some things have changed since (like the move route commands that changed between v20.1 and v21+ of pokemon essentials) but you should be able to replicate the changes I did for this.

Most of the code for the pbNewSecretBase (in Base Creation Interaction Exterior) is the original one so copy that (or undo the changes on it). Then you have to copy the conditionals that use if SecretBaseSettings::SECRET_BASE_SPECIAL.include?(GameData::SecretBase.get(player_base.id).type) when closing a secret base (they are before a line with # Now check for the base type. and are used to give the player some money for selling the base).

The code in the conditional after the # Now check for the base type. is for creating the base and is duplicated. The part after the else of the condition is the original code of the plugin so keep it that way. The part between the if and else is where the code for buying is done. Copy the original code for creating the base and add the edits of the messages and the checks on whether the player can keep the secret base or not.

If you don't know how to do it, I'll download the newest version (if I don't have it already) and post my try with the changes.

If you don't mind making the change for the update I would be really grateful! I'm new to coding and this manipulation is a bit too advanced for me😅
 

LinKazamine

Champion
Member
Joined
May 24, 2023
Posts
683
Ok, after looking at the code of v3.0.0, it seems the only real change is that the move route changed from "Up" (v20.1) to "UP" (v21+). If you don't want to copy it all again (and risk deleting something by mistake) you only have to search for "PBMoveRoute::Up" and change it to "PBMoveRoute::UP". If not, here is the code:
Ruby:
Expand Collapse Copy
# This is the method for the talk to base.
def pbNewSecretBase(base_id)
  # no prompt if this is an open base.
  return if SecretBaseMethods.is_active_secret_base?(base_id)
  move = SecretBaseSettings::SECRET_BASE_MOVE_NEEDED
  movefinder = $player.get_pokemon_with_move(move)
  base_data = GameData::SecretBase.get(base_id)
  template_data = GameData::SecretBaseTemplate.get(base_data.map_template)
  messages_anim = SecretBaseSettings::SECRET_BASE_MESSAGES_ANIM[template_data.type]
  if (!$DEBUG && !movefinder)
    # No mon that can use the Secret Base Move, abort.
    pbMessage(_INTL(messages_anim[0]))
    return
  end
  player_base = $PokemonGlobal.secret_base_list[0]
  moved_bases = false
  if player_base.id && player_base.id != base_id
    # semi-redundant check, but if the player has a base at all (id is not nil), and it's not this one.
    map_name = pbGetMapNameFromId(GameData::SecretBase.get(player_base.id).location[0])
    pbMessage(_INTL("You may only make one Secret Base.\\1"))
    if pbConfirmMessage(_INTL("Would you like to move from the Secret Base near {1}?",map_name))
      pbMessage(_INTL("All decorations and furniture in your Secret Base will be returned to your PC.\\1"))
      if SecretBaseSettings::SECRET_BASE_SPECIAL.include?(GameData::SecretBase.get(player_base.id).type)
        sellPrice = GameData::SecretBase.get(player_base.id).sell_price
        pbMessage(_INTL("You will receive $ {1} for selling this Secret Base.\\1", sellPrice))
      end
      if pbConfirmMessage(_INTL("Is that okay?"))
        if SecretBaseSettings::SECRET_BASE_SPECIAL.include?(GameData::SecretBase.get(player_base.id).type)
          $player.money += sellPrice
        end
        # Pack up the base.
        pbFadeOutIn {
          player_base.remove_decorations((0...SecretBaseSettings::SECRET_BASE_MAX_DECORATIONS).to_a)
          $secret_bag.unplace_all
          player_base.id = nil
        }
        pbMessage(_INTL("Moving completed.\\1"))
        $stats.moved_secret_base_count+=1
        moved_bases = true
      else
        return
      end
    else
      return
    end
  end
  if !moved_bases
    pbMessage(sprintf("%s\\1",_INTL(messages_anim[0])))
  end
  # Now ¡check for the base type.
  if SecretBaseSettings::SECRET_BASE_SPECIAL.include?(template_data.type)
    _, x, y = pbFacingTile
    spriteset = $scene.spriteset($game_map.map_id)
    sprite = spriteset&.addUserAnimation(messages_anim[2], x, y, true, 1)
    SecretBaseMethods.animate_base_opening(base_id, sprite,messages_anim[2],messages_anim[3])
    pbMessage(_INTL(messages_anim[1]))
    pbSEPlay("Door Exit", 80, 100)
    dx,dy = template_data.door_location
    pbFadeOutIn(99999){
      $game_temp.player_transferring   = true
      $game_temp.transition_processing = true
      $game_temp.player_new_map_id    = SecretBaseSettings::SECRET_BASE_MAP
      $game_temp.player_new_x         = dx
      $game_temp.player_new_y         = dy-1
      $game_temp.player_new_direction = 8
      $scene.transfer_player
    }
    move_route=[]
    template_data.preview_steps.times do
      move_route.push(PBMoveRoute::UP)
    end
    pbMoveRoute($game_player,move_route)
    loop do
      Graphics.update
      Input.update
      pbUpdateSceneMap
      break unless $game_player.move_route_forcing
    end
    price = base_data.price
      if !pbConfirmMessage(_INTL("\\GWant to make your Secret Base here?\nIt costs $ {1}.",price.to_s_formatted))
        pbFadeOutIn(99999){
          $game_temp.player_transferring   = true
          $game_temp.transition_processing = true
          $game_temp.player_new_map_id    = base_data.location[0]
          $game_temp.player_new_x         = base_data.location[1]
          $game_temp.player_new_y         = base_data.location[2]+1
          $game_temp.player_new_direction = 2
          $scene.transfer_player
        }
      else
        if $player.money < price
          pbMessage(_INTL("You don't have enough money."))
          pbFadeOutIn(99999){
            $game_temp.player_transferring   = true
            $game_temp.transition_processing = true
            $game_temp.player_new_map_id    = base_data.location[0]
            $game_temp.player_new_x         = base_data.location[1]
            $game_temp.player_new_y         = base_data.location[2]+1
            $game_temp.player_new_direction = 2
            $scene.transfer_player
          }
        else
          $player.money -= price
          px,py = template_data.pc_location
          pbFadeOutIn(99999){
            $PokemonMap.current_base_id = base_id
            player_base.id = base_id
            $game_temp.player_transferring   = true
            $game_temp.transition_processing = true
            $game_temp.player_new_map_id    = SecretBaseSettings::SECRET_BASE_MAP
            $game_temp.player_new_x         = px
            $game_temp.player_new_y         = py+1
            $game_temp.player_new_direction = 8
            $scene.transfer_player
          }
        end
      end
  else
    # Now we ask to use the Secret Base Move.
    if pbConfirmMessage(_INTL("Would you like to use the {1}?",GameData::Move.get(move).name))
      speciesname = (movefinder) ? movefinder.name : $player.name
      pbMessage(_INTL("{1} used {2}!", speciesname, GameData::Move.get(move).name))
      pbHiddenMoveAnimation(movefinder)
      _, x, y = pbFacingTile
      spriteset = $scene.spriteset($game_map.map_id)
      sprite = spriteset&.addUserAnimation(messages_anim[2], x, y, true, 1)
      SecretBaseMethods.animate_base_opening(base_id, sprite,messages_anim[2],messages_anim[3])
      pbMessage(_INTL(messages_anim[1]))
      pbSEPlay("Door Exit", 80, 100)
      dx,dy = template_data.door_location
      pbFadeOutIn(99999){
        $game_temp.player_transferring   = true
        $game_temp.transition_processing = true
        $game_temp.player_new_map_id    = SecretBaseSettings::SECRET_BASE_MAP
        $game_temp.player_new_x         = dx
        $game_temp.player_new_y         = dy-1
        $game_temp.player_new_direction = 8
        $scene.transfer_player
      }
      move_route=[]
      template_data.preview_steps.times do
        move_route.push(PBMoveRoute::UP)
      end
      pbMoveRoute($game_player,move_route)
      loop do
        Graphics.update
        Input.update
        pbUpdateSceneMap
        break unless $game_player.move_route_forcing
      end
      if !pbConfirmMessage(_INTL("Want to make your Secret Base here?"))
        pbFadeOutIn(99999){
          $game_temp.player_transferring   = true
          $game_temp.transition_processing = true
          $game_temp.player_new_map_id    = base_data.location[0]
          $game_temp.player_new_x         = base_data.location[1]
          $game_temp.player_new_y         = base_data.location[2]+1
          $game_temp.player_new_direction = 2
          $scene.transfer_player
        }
      else
        px,py = template_data.pc_location
        pbFadeOutIn(99999){
          $PokemonMap.current_base_id = base_id
          player_base.id = base_id
          $game_temp.player_transferring   = true
          $game_temp.transition_processing = true
          $game_temp.player_new_map_id    = SecretBaseSettings::SECRET_BASE_MAP
          $game_temp.player_new_x         = px
          $game_temp.player_new_y         = py+1
          $game_temp.player_new_direction = 8
          $scene.transfer_player
        }
      end
    end
  end
end
 

Hiyouri

Novice
Member
Joined
Aug 13, 2024
Posts
17
Ok, after looking at the code of v3.0.0, it seems the only real change is that the move route changed from "Up" (v20.1) to "UP" (v21+). If you don't want to copy it all again (and risk deleting something by mistake) you only have to search for "PBMoveRoute::Up" and change it to "PBMoveRoute::UP". If not, here is the code:
Ruby:
Expand Collapse Copy
# This is the method for the talk to base.
def pbNewSecretBase(base_id)
  # no prompt if this is an open base.
  return if SecretBaseMethods.is_active_secret_base?(base_id)
  move = SecretBaseSettings::SECRET_BASE_MOVE_NEEDED
  movefinder = $player.get_pokemon_with_move(move)
  base_data = GameData::SecretBase.get(base_id)
  template_data = GameData::SecretBaseTemplate.get(base_data.map_template)
  messages_anim = SecretBaseSettings::SECRET_BASE_MESSAGES_ANIM[template_data.type]
  if (!$DEBUG && !movefinder)
    # No mon that can use the Secret Base Move, abort.
    pbMessage(_INTL(messages_anim[0]))
    return
  end
  player_base = $PokemonGlobal.secret_base_list[0]
  moved_bases = false
  if player_base.id && player_base.id != base_id
    # semi-redundant check, but if the player has a base at all (id is not nil), and it's not this one.
    map_name = pbGetMapNameFromId(GameData::SecretBase.get(player_base.id).location[0])
    pbMessage(_INTL("You may only make one Secret Base.\\1"))
    if pbConfirmMessage(_INTL("Would you like to move from the Secret Base near {1}?",map_name))
      pbMessage(_INTL("All decorations and furniture in your Secret Base will be returned to your PC.\\1"))
      if SecretBaseSettings::SECRET_BASE_SPECIAL.include?(GameData::SecretBase.get(player_base.id).type)
        sellPrice = GameData::SecretBase.get(player_base.id).sell_price
        pbMessage(_INTL("You will receive $ {1} for selling this Secret Base.\\1", sellPrice))
      end
      if pbConfirmMessage(_INTL("Is that okay?"))
        if SecretBaseSettings::SECRET_BASE_SPECIAL.include?(GameData::SecretBase.get(player_base.id).type)
          $player.money += sellPrice
        end
        # Pack up the base.
        pbFadeOutIn {
          player_base.remove_decorations((0...SecretBaseSettings::SECRET_BASE_MAX_DECORATIONS).to_a)
          $secret_bag.unplace_all
          player_base.id = nil
        }
        pbMessage(_INTL("Moving completed.\\1"))
        $stats.moved_secret_base_count+=1
        moved_bases = true
      else
        return
      end
    else
      return
    end
  end
  if !moved_bases
    pbMessage(sprintf("%s\\1",_INTL(messages_anim[0])))
  end
  # Now ¡check for the base type.
  if SecretBaseSettings::SECRET_BASE_SPECIAL.include?(template_data.type)
    _, x, y = pbFacingTile
    spriteset = $scene.spriteset($game_map.map_id)
    sprite = spriteset&.addUserAnimation(messages_anim[2], x, y, true, 1)
    SecretBaseMethods.animate_base_opening(base_id, sprite,messages_anim[2],messages_anim[3])
    pbMessage(_INTL(messages_anim[1]))
    pbSEPlay("Door Exit", 80, 100)
    dx,dy = template_data.door_location
    pbFadeOutIn(99999){
      $game_temp.player_transferring   = true
      $game_temp.transition_processing = true
      $game_temp.player_new_map_id    = SecretBaseSettings::SECRET_BASE_MAP
      $game_temp.player_new_x         = dx
      $game_temp.player_new_y         = dy-1
      $game_temp.player_new_direction = 8
      $scene.transfer_player
    }
    move_route=[]
    template_data.preview_steps.times do
      move_route.push(PBMoveRoute::UP)
    end
    pbMoveRoute($game_player,move_route)
    loop do
      Graphics.update
      Input.update
      pbUpdateSceneMap
      break unless $game_player.move_route_forcing
    end
    price = base_data.price
      if !pbConfirmMessage(_INTL("\\GWant to make your Secret Base here?\nIt costs $ {1}.",price.to_s_formatted))
        pbFadeOutIn(99999){
          $game_temp.player_transferring   = true
          $game_temp.transition_processing = true
          $game_temp.player_new_map_id    = base_data.location[0]
          $game_temp.player_new_x         = base_data.location[1]
          $game_temp.player_new_y         = base_data.location[2]+1
          $game_temp.player_new_direction = 2
          $scene.transfer_player
        }
      else
        if $player.money < price
          pbMessage(_INTL("You don't have enough money."))
          pbFadeOutIn(99999){
            $game_temp.player_transferring   = true
            $game_temp.transition_processing = true
            $game_temp.player_new_map_id    = base_data.location[0]
            $game_temp.player_new_x         = base_data.location[1]
            $game_temp.player_new_y         = base_data.location[2]+1
            $game_temp.player_new_direction = 2
            $scene.transfer_player
          }
        else
          $player.money -= price
          px,py = template_data.pc_location
          pbFadeOutIn(99999){
            $PokemonMap.current_base_id = base_id
            player_base.id = base_id
            $game_temp.player_transferring   = true
            $game_temp.transition_processing = true
            $game_temp.player_new_map_id    = SecretBaseSettings::SECRET_BASE_MAP
            $game_temp.player_new_x         = px
            $game_temp.player_new_y         = py+1
            $game_temp.player_new_direction = 8
            $scene.transfer_player
          }
        end
      end
  else
    # Now we ask to use the Secret Base Move.
    if pbConfirmMessage(_INTL("Would you like to use the {1}?",GameData::Move.get(move).name))
      speciesname = (movefinder) ? movefinder.name : $player.name
      pbMessage(_INTL("{1} used {2}!", speciesname, GameData::Move.get(move).name))
      pbHiddenMoveAnimation(movefinder)
      _, x, y = pbFacingTile
      spriteset = $scene.spriteset($game_map.map_id)
      sprite = spriteset&.addUserAnimation(messages_anim[2], x, y, true, 1)
      SecretBaseMethods.animate_base_opening(base_id, sprite,messages_anim[2],messages_anim[3])
      pbMessage(_INTL(messages_anim[1]))
      pbSEPlay("Door Exit", 80, 100)
      dx,dy = template_data.door_location
      pbFadeOutIn(99999){
        $game_temp.player_transferring   = true
        $game_temp.transition_processing = true
        $game_temp.player_new_map_id    = SecretBaseSettings::SECRET_BASE_MAP
        $game_temp.player_new_x         = dx
        $game_temp.player_new_y         = dy-1
        $game_temp.player_new_direction = 8
        $scene.transfer_player
      }
      move_route=[]
      template_data.preview_steps.times do
        move_route.push(PBMoveRoute::UP)
      end
      pbMoveRoute($game_player,move_route)
      loop do
        Graphics.update
        Input.update
        pbUpdateSceneMap
        break unless $game_player.move_route_forcing
      end
      if !pbConfirmMessage(_INTL("Want to make your Secret Base here?"))
        pbFadeOutIn(99999){
          $game_temp.player_transferring   = true
          $game_temp.transition_processing = true
          $game_temp.player_new_map_id    = base_data.location[0]
          $game_temp.player_new_x         = base_data.location[1]
          $game_temp.player_new_y         = base_data.location[2]+1
          $game_temp.player_new_direction = 2
          $scene.transfer_player
        }
      else
        px,py = template_data.pc_location
        pbFadeOutIn(99999){
          $PokemonMap.current_base_id = base_id
          player_base.id = base_id
          $game_temp.player_transferring   = true
          $game_temp.transition_processing = true
          $game_temp.player_new_map_id    = SecretBaseSettings::SECRET_BASE_MAP
          $game_temp.player_new_x         = px
          $game_temp.player_new_y         = py+1
          $game_temp.player_new_direction = 8
          $scene.transfer_player
        }
      end
    end
  end
end

It's fixed but now I have this:
Exception `NoMethodError' at [Secret Bases Remade] 005_Base_Creation_Interaction_Exterior.rb:189 - undefined method `to_s_formatted' for nil:NilClass
Do you think its beacause i have the following pokemon plugin?
 

LinKazamine

Champion
Member
Joined
May 24, 2023
Posts
683
That error has nothing to do with other plugins. What it's telling you is that it can't get the base's price for some reason.

Ah, it seems that for the v21 of the plugin there were changes to the other two files I edited too.
For the v21, there was no need to change the code for [001] New GameData/005_Compiler_Changes. It may cause trouble to edit it, so try to replace that file with the original one. Maybe that would solve the error?
As for [001] New GameData/002_SecretBase, that does need to be edited so here is the code:
Ruby:
Expand Collapse Copy
module GameData
  class SecretBase
    attr_reader :id
    attr_reader :map_template
    attr_reader :location
    attr_reader :pbs_file_suffix
    attr_reader :price
    attr_reader :sell_price

    DATA = {}
    DATA_FILENAME = "secret_bases.dat"
    PBS_BASE_FILENAME = "secret_bases"

    extend ClassMethodsSymbols
    include InstanceMethods

    SCHEMA = {
      "SectionName"  => [:id,           "m"],
      "MapTemplate"  => [:map_template, "e", :SecretBaseTemplate],
      "Location"     => [:location, "vuu"],
      "Price"        => [:price, "u"],
      "SellPrice"    => [:sell_price,  "u"]
    }

    def initialize(hash)
      @id              = hash[:id]
      @map_template    = hash[:map_template]
      @location        = hash[:location]
      @pbs_file_suffix = hash[:pbs_file_suffix] || ""
      @price           = hash[:price]       || 0
      @sell_price      = hash[:sell_price]  || (@price / 2)
    end
  end
end

If that still doesn't solve the problem, I'm not sure where that may be since the price should be 0 if none was defined on the PBS.
 

Hiyouri

Novice
Member
Joined
Aug 13, 2024
Posts
17
That error has nothing to do with other plugins. What it's telling you is that it can't get the base's price for some reason.

Ah, it seems that for the v21 of the plugin there were changes to the other two files I edited too.
For the v21, there was no need to change the code for [001] New GameData/005_Compiler_Changes. It may cause trouble to edit it, so try to replace that file with the original one. Maybe that would solve the error?
As for [001] New GameData/002_SecretBase, that does need to be edited so here is the code:
Ruby:
Expand Collapse Copy
module GameData
  class SecretBase
    attr_reader :id
    attr_reader :map_template
    attr_reader :location
    attr_reader :pbs_file_suffix
    attr_reader :price
    attr_reader :sell_price

    DATA = {}
    DATA_FILENAME = "secret_bases.dat"
    PBS_BASE_FILENAME = "secret_bases"

    extend ClassMethodsSymbols
    include InstanceMethods

    SCHEMA = {
      "SectionName"  => [:id,           "m"],
      "MapTemplate"  => [:map_template, "e", :SecretBaseTemplate],
      "Location"     => [:location, "vuu"],
      "Price"        => [:price, "u"],
      "SellPrice"    => [:sell_price,  "u"]
    }

    def initialize(hash)
      @id              = hash[:id]
      @map_template    = hash[:map_template]
      @location        = hash[:location]
      @pbs_file_suffix = hash[:pbs_file_suffix] || ""
      @price           = hash[:price]       || 0
      @sell_price      = hash[:sell_price]  || (@price / 2)
    end
  end
end

If that still doesn't solve the problem, I'm not sure where that may be since the price should be 0 if none was defined on the PBS.

Finally, I made it! Thank you very much my friend!
 

Hiyouri

Novice
Member
Joined
Aug 13, 2024
Posts
17
do you think its possible to add manually a secret base with a script call?
 
Back
Top