• Hi, Guest!
    Some images might be missing as we move away from using embedded images, sorry for the mess!
    From now on, you'll be required to use a third party to host images. You can learn how to add images here, and if your thread is missing images you can request them here.
    Do not use Discord to host any images you post, these links expire quickly!
Resource icon

v21.1 Water current/ treadmills for Essentials v21.1 1.0

This resource pertains to version 21.1 of Pokémon Essentials.
It is possible to find how to make water currents in version 20 and 20.1, but it does not work properly in version v21.1, I made the changes about a few months ago in the original post, but many may not have seen it.
So I bring here the updated tutorial.
The mat part is optional, I left it separate because before there was a bug that you couldn't surf, so I separated the mats so as not to use surfing on them


this is the old tutorial:
Water current V20/20.1



changes are made to the game's base scripts, so make a backup beforehand to avoid losing your project.

STEP 1 : TerrainTag section
In your script editor, go in the TerrainTag section and look for attr_reader :ignore_passability.
Add attr_reader :water_current on the next line.

Then, look for @ignore_passability in the same section, and add @water_current = hash[:water_current] || false on the next line.
This should look like this :
TerrainTag:
module GameData
  class TerrainTag
    attr_reader :id
    attr_reader :id_number
    attr_reader :real_name
    attr_reader :can_surf
    attr_reader :waterfall   # The main part only, not the crest
    attr_reader :waterfall_crest
    attr_reader :can_fish
    attr_reader :can_dive
    attr_reader :deep_bush
    attr_reader :shows_grass_rustle
    attr_reader :land_wild_encounters
    attr_reader :double_wild_encounters
    attr_reader :battle_environment
    attr_reader :ledge
    attr_reader :ice
    attr_reader :bridge
    attr_reader :shows_reflections
    attr_reader :must_walk
    attr_reader :must_walk_or_run
    attr_reader :ignore_passability
    attr_reader :water_current
    attr_reader :treadmills
    DATA = {}

    extend ClassMethods
    include InstanceMethods

    # @param other [Symbol, self, String, Integer]
    # @return [self]
    def self.try_get(other)
      return self.get(:None) if other.nil?
      validate other => [Symbol, self, String, Integer]
      return other if other.is_a?(self)
      other = other.to_sym if other.is_a?(String)
      return (self::DATA.has_key?(other)) ? self::DATA[other] : self.get(:None)
    end

    def self.load; end
    def self.save; end

    def initialize(hash)
      @id                     = hash[:id]
      @id_number              = hash[:id_number]
      @real_name              = hash[:id].to_s                || "Unnamed"
      @can_surf               = hash[:can_surf]               || false
      @waterfall              = hash[:waterfall]              || false
      @waterfall_crest        = hash[:waterfall_crest]        || false
      @can_fish               = hash[:can_fish]               || false
      @can_dive               = hash[:can_dive]               || false
      @deep_bush              = hash[:deep_bush]              || false
      @shows_grass_rustle     = hash[:shows_grass_rustle]     || false
      @land_wild_encounters   = hash[:land_wild_encounters]   || false
      @double_wild_encounters = hash[:double_wild_encounters] || false
      @battle_environment     = hash[:battle_environment]
      @ledge                  = hash[:ledge]                  || false
      @ice                    = hash[:ice]                    || false
      @bridge                 = hash[:bridge]                 || false
      @shows_reflections      = hash[:shows_reflections]      || false
      @must_walk              = hash[:must_walk]              || false
      @must_walk_or_run       = hash[:must_walk_or_run]       || false
      @ignore_passability     = hash[:ignore_passability]     || false
      @water_current          = hash[:water_current]          || false
      @treadmills             = hash[:treadmills]             || false
    end

    alias name real_name

    def can_surf_freely
      return @can_surf && !@waterfall && !@waterfall_crest
    end
  end
end
Now, at the end of the section, add these four terrain tag registrations after the :NoEffect one. If you already have scripts that add new terrain tags, change the id numbers (18, 19, 20 and 21) so they don't clash with other id's.

This should look like this :

Ruby:
GameData::TerrainTag.register({
  :id                     => :currentNorth,
  :id_number              => 18,
  :can_surf               => true,
  :water_current          => true
})

GameData::TerrainTag.register({
  :id                     => :currentEast,
  :id_number              => 19,
  :can_surf               => true,
  :water_current          => true
})

GameData::TerrainTag.register({
  :id                     => :currentWest,
  :id_number              => 20,
  :can_surf               => true,
  :water_current          => true
})

GameData::TerrainTag.register({
  :id                     => :currentSouth,
  :id_number              => 21,
  :can_surf               => true,
  :water_current          => true
})

GameData::TerrainTag.register({
  :id                     => :treadmillsNorth,
  :id_number              => 30,
  :treadmills          => true
})

GameData::TerrainTag.register({
  :id                     => :treadmillsEast,
  :id_number              => 31,
  :treadmills          => true
})

GameData::TerrainTag.register({
  :id                     => :treadmillsWest,
  :id_number              => 32,
  :treadmills          => true
})

GameData::TerrainTag.register({
  :id                     => :treadmillsSouth,
  :id_number              => 33,
  :treadmills          => true

These terrain tags will be responsible for identifying in which direction the player will be launched, remember, you need:
1- enter the game
2- access the debug menu
3- go to other editors
4- edit terracing tag
5- choose the tileset
6-add the tag corresponding to the direction you want on the graph, it also works with autotile.

STEP 2: Overworld script

in the overworld script, in the part where it says " # Auto-move the player over waterfalls and ice" , add:
elsif currentTag.water_current || $PokemonGlobal.sliding
pbWaterCurrent

elsif currentTag.treadmills || $PokemonGlobal.sliding
pbtreadmills


ending up like this:
Ruby:
# Auto-move the player over waterfalls and ice
EventHandlers.add(:on_step_taken, :auto_move_player,
  proc { |event|
    next if !$scene.is_a?(Scene_Map)
    next if event != $game_player
    currentTag = $game_player.pbTerrainTag
    if currentTag.waterfall_crest || currentTag.waterfall ||
       $PokemonGlobal.descending_waterfall || $PokemonGlobal.ascending_waterfall
      pbTraverseWaterfall
    elsif currentTag.ice || $PokemonGlobal.ice_sliding
      pbSlideOnIce
[COLOR=rgb(41, 105, 176)]      elsif currentTag.water_current || $PokemonGlobal.sliding
      pbWaterCurrent[/COLOR]
 [COLOR=rgb(184, 49, 47)]  elsif currentTag.treadmills || $PokemonGlobal.sliding
      pbtreadmills[/COLOR]
    end
  }
)

STEP 3: Adding pbWaterCurrent
still in overworld script search for: def pbMoveTowardPlayer(event)

and after end, add this:
Ruby:
def pbWaterCurrent
  if !$DEBUG || !Input.press?(Input::CTRL)
    return if !$game_player.pbTerrainTag.water_current
    $game_temp.followers.update
    $PokemonGlobal.sliding = true
    in_water_current = true
    direction = $game_player.direction
    oldwalkanime = $game_player.walk_anime
    first_loop = true

    loop do
      if in_water_current
        case $game_player.pbTerrainTag.id
        when :currentNorth
          direction = 8
        when :currentEast
          direction = 6
        when :currentSouth
          direction = 2
        when :currentWest
          direction = 4
        end
      end

      break if !$game_player.pbTerrainTag.water_current

      if direction == $game_player.direction
        $game_player.move_forward
      else
        in_water_current = false
        case direction
        when 8
          $game_player.move_up
        when 6
          $game_player.move_right
        when 2
          $game_player.move_down
        when 4
          $game_player.move_left
        end
      end

      $game_temp.followers.move_followers if first_loop

      while $game_player.moving?
        pbUpdateSceneMap
        Graphics.update
        Input.update
      end
      first_loop = false

      while $game_player.moving?
        Graphics.update
        Input.update
        pbUpdateSceneMap
      end

      $game_player.center($game_player.x, $game_player.y)
      $game_player.straighten
      $game_player.walk_anime = oldwalkanime
      $PokemonGlobal.sliding = false
    end
  end
end
def pbtreadmills
  if !$DEBUG || !Input.press?(Input::CTRL)
    return if !$game_player.pbTerrainTag.treadmills
    $game_temp.followers.update
    $PokemonGlobal.sliding = true
    in_treadmills = true
    direction = $game_player.direction
    oldwalkanime = $game_player.walk_anime
    first_loop = true

    loop do
      if in_treadmills
        case $game_player.pbTerrainTag.id
        when :treadmillsNorth
          direction = 8
        when :treadmillsEast
          direction = 6
        when :treadmillsSouth
          direction = 2
        when :treadmillsWest
          direction = 4
        end
      end

      break if !$game_player.pbTerrainTag.treadmills

      if direction == $game_player.direction
        $game_player.move_forward
      else
        in_treadmills = false
        case direction
        when 8
          $game_player.move_up
        when 6
          $game_player.move_right
        when 2
          $game_player.move_down
        when 4
          $game_player.move_left
        end
      end

      $game_temp.followers.move_followers if first_loop

      while $game_player.moving?
        pbUpdateSceneMap
        Graphics.update
        Input.update
      end
      first_loop = false

      while $game_player.moving?
        Graphics.update
        Input.update
        pbUpdateSceneMap
      end

      $game_player.center($game_player.x, $game_player.y)
      $game_player.straighten
      $game_player.walk_anime = oldwalkanime
      $PokemonGlobal.sliding = false
    end
  end
end

This part is responsible for associating the directions the player will go with the previously mentioned Terraintag.

STEP 4: Overworld_Metadata session

In "Overworld_Metadata", add the following to the "PokemonGlobalMetadata" class, in the # Movement part, add:
attr_accessor :sliding

it will look like this:
Ruby:
class PokemonGlobalMetadata
  # Movement
  attr_accessor :bicycle
  attr_accessor :surfing
  attr_accessor :diving
  attr_accessor :ice_sliding
  attr_accessor :sliding
  attr_accessor :descending_waterfall
  attr_accessor :ascending_waterfall
  attr_accessor :fishing

attr_accessor :sliding is essential for step 2 and 3 to work
STEP 5: Returns whether the player's current location allows wild encounters
in the Overworld Wild Encounters script, paste before the last return false in def encounter_possible_here?

return false if terrain_tag.water_current
like this:
Ruby:
  def encounter_possible_here?
    return true if $PokemonGlobal.surfing
    terrain_tag = $game_map.terrain_tag($game_player.x, $game_player.y)
    return false if terrain_tag.ice
    return true if has_cave_encounters?   # i.e. this map is a cave
    return true if has_land_encounters? && terrain_tag.land_wild_encounters
   return false if terrain_tag.water_current
   return false if terrain_tag.treadmills
   return false
  end

STEP 6: test


the same terraingtags can be used if you want to do other things, like electric treadmills.
I will leave the autotiles I use available for testing, and I repeat, don't forget to make a backup!!

future improvements:


There is a bug when using the default essentials graphics.
In this case, surf and dive have 2 separate graphics, the base and the palyer, if you use surf directly in a watercurrent, only the player moves and the surf base does not, to avoid this, if it does not affect your game, combine the charts are surf base with the two palyer and leave the surf chart invisible. For now I don't have a plan on how to fix this.

I could do it as a plugin, but I don't really understand how to make it work correctly, if you wanted to make a plugin and update, feel free.
Credits
ChromusSama => main script
Vendily and Techskylander1518 => helping fixing a bug
Rafahbit = > portability to essentials v21.1
  • SpinDown.png
    SpinDown.png
    306 bytes · Views: 35
  • SpinLeft.png
    SpinLeft.png
    283 bytes · Views: 39
  • Spinright.png
    Spinright.png
    283 bytes · Views: 31
  • SpinUp.png
    SpinUp.png
    309 bytes · Views: 42
  • Water current east.png
    Water current east.png
    523 bytes · Views: 38
  • Water current north.png
    Water current north.png
    591 bytes · Views: 38
  • Water current south.png
    Water current south.png
    579 bytes · Views: 28
  • Water current west.png
    Water current west.png
    548 bytes · Views: 37
  • Like
Reactions: ardicoozer
Author
rafahbit
Views
978
First release
Last update
Rating
0.00 star(s) 0 ratings
Back
Top