12 Commits

Author SHA1 Message Date
chardub
13c7792686 dna splicers that don't crash the game... 2025-05-09 20:30:35 -04:00
chardub
4ecf97b777 DNA Splicers WIP 2025-05-08 22:59:30 -04:00
chardub
6536fcda77 More characters customization 2025-04-27 12:17:35 -04:00
chardub
4a19fbc754 Outfits migration again 2025-04-27 00:37:26 -04:00
chardub
c0cf7da7bb Overworld Outfits 2025-04-27 00:14:10 -04:00
chardub
bbd5ba09ea More migration 2025-04-26 22:03:51 -04:00
chardub
90c0e51e88 Caches expanded autotiles to reduce stutter caused by map connections 2025-04-26 22:01:12 -04:00
chardub
85d5f6206c custom autotile replacements 2025-04-26 21:35:28 -04:00
chardub
b412ad7b39 Migration - more progress 2025-04-25 22:06:46 -04:00
chardub
7de024dafd Renames $Trainer to $player 2025-04-24 19:57:12 -04:00
chardub
95ef337de8 Migrate a reorganizes bunch of files from PIF 2025-04-24 19:46:52 -04:00
chardub
682323e255 feature(Implements speed up) 2025-04-19 10:59:33 -04:00
429 changed files with 41561 additions and 58659 deletions

Binary file not shown.

View File

@@ -203,41 +203,41 @@ module Settings
# * :areas - A hash of map IDs that determine where this Pokémon roams. Used
# instead of ROAMING_AREAS above. Optional.
ROAMING_SPECIES = [
{
:species => :LATIAS,
:level => 30,
:icon => "pin_latias",
:game_switch => 53,
:encounter_type => :all,
:bgm => "Battle roaming"
},
{
:species => :LATIOS,
:level => 30,
:icon => "pin_latios",
:game_switch => 53,
:encounter_type => :all,
:bgm => "Battle roaming"
},
{
:species => :KYOGRE,
:level => 40,
:game_switch => 54,
:encounter_type => :surfing,
:areas => {
2 => [ 21, 31 ],
21 => [2, 31, 69],
31 => [2, 21, 69],
69 => [ 21, 31 ]
}
},
{
:species => :ENTEI,
:level => 40,
:icon => "pin_entei",
:game_switch => 55,
:encounter_type => :land
}
# {
# :species => :LATIAS,
# :level => 30,
# :icon => "pin_latias",
# :game_switch => 53,
# :encounter_type => :all,
# :bgm => "Battle roaming"
# },
# {
# :species => :LATIOS,
# :level => 30,
# :icon => "pin_latios",
# :game_switch => 53,
# :encounter_type => :all,
# :bgm => "Battle roaming"
# },
# {
# :species => :KYOGRE,
# :level => 40,
# :game_switch => 54,
# :encounter_type => :surfing,
# :areas => {
# 2 => [ 21, 31 ],
# 21 => [2, 31, 69],
# 31 => [2, 21, 69],
# 69 => [ 21, 31 ]
# }
# },
# {
# :species => :ENTEI,
# :level => 40,
# :icon => "pin_entei",
# :game_switch => 55,
# :encounter_type => :land
# }
]
#-----------------------------------------------------------------------------

View File

@@ -45,8 +45,11 @@ module Kernel
end
def echoln(string)
echo string
echo "\n"
caller_info = caller(1..1).first
file, line, method = caller_info.split(":")
echo "#{file}, #{line}:\t"
echo(string)
echo("\r\n")
end
end

View File

@@ -35,6 +35,8 @@ module Game
# Called when starting a new game. Initializes global variables
# and transfers the player into the map scene.
def start_new
# Essentials 21 renamed the global variable $Trainer
# It's still used everywhere in events, global events so this makes things simpler
if $game_map&.events
$game_map.events.each_value { |event| event.clear_starting }
end
@@ -58,6 +60,11 @@ module Game
# @param save_data [Hash] hash containing the save data
# @raise [SaveData::InvalidValueError] if an invalid value is being loaded
def load(save_data)
# Essentials 21 renamed the global variable $Trainer
# It's still used everywhere in events, global events so this makes things simpler
$Trainer = $player
validate save_data => Hash
SaveData.load_all_values(save_data)
$game_temp.last_uptime_refreshed_play_time = System.uptime

View File

@@ -51,7 +51,7 @@ class Interpreter
when 134 then return command_134 # Change Save Access
when 135 then return command_135 # Change Menu Access
when 136 then return command_136 # Change Encounter
when 201 then return command_201 # Transfer Player
when 201 then return command_201 # Transfer Overrides
when 202 then return command_202 # Set Event Location
when 203 then return command_203 # Scroll Map
when 204 then return command_204 # Change Map Settings
@@ -731,7 +731,7 @@ class Interpreter
end
#-----------------------------------------------------------------------------
# * Transfer Player
# * Transfer Overrides
#-----------------------------------------------------------------------------
def command_201
return true if $game_temp.in_battle

View File

@@ -28,7 +28,7 @@ class Game_Temp
attr_accessor :force_single_battle # force next battle to be 1v1 flag
attr_accessor :waiting_trainer # [trainer, event ID] or nil
attr_accessor :last_battle_record # record of actions in last recorded battle
# Player transfers
# Overrides transfers
attr_accessor :player_transferring # player place movement flag
attr_accessor :player_new_map_id # player destination: map ID
attr_accessor :player_new_x # player destination: x-coordinate
@@ -67,7 +67,7 @@ class Game_Temp
# Battle
@battleback_name = ""
@force_single_battle = false
# Player transfers
# Overrides transfers
@player_transferring = false
@player_new_map_id = 0
@player_new_x = 0

View File

@@ -118,7 +118,7 @@ class Game_Player < Game_Character
def bump_into_object
return if @bump_time_start && (System.uptime - @bump_time_start < @move_time)
pbSEPlay("Player bump") if !@move_route_forcing
pbSEPlay("Overrides bump") if !@move_route_forcing
$stats.bump_count += 1
@bump_time_start = System.uptime
end
@@ -143,7 +143,7 @@ class Game_Player < Game_Character
# Jump over ledges
if pbFacingTerrainTag.ledge
if jumpForward(2)
pbSEPlay("Player jump")
pbSEPlay("Overrides jump")
increase_steps
end
return
@@ -389,7 +389,7 @@ class Game_Player < Game_Character
x_offset = (dir == 4) ? -1 : (dir == 6) ? 1 : 0
y_offset = (dir == 8) ? -1 : (dir == 2) ? 1 : 0
$game_map.events.each_value do |event|
next if ![1, 2].include?(event.trigger) # Player touch, event touch
next if ![1, 2].include?(event.trigger) # Overrides touch, event touch
# If event coordinates and triggers are consistent
next if !event.at_coordinate?(@x + x_offset, @y + y_offset)
if event.name[/(?:sight|trainer)\((\d+)\)/i]

View File

@@ -111,6 +111,7 @@ class Sprite_Character < RPG::Sprite
@charbitmap = nil
@bushbitmap&.dispose
@bushbitmap = nil
if @tile_id >= 384
@charbitmap = pbGetTileBitmap(@character.map.tileset_name, @tile_id,
@character_hue, @character.width, @character.height)

View File

@@ -2,28 +2,28 @@
#
#===============================================================================
class TilemapRenderer
attr_reader :tilesets
attr_reader :autotiles
attr_reader :tilesets
attr_reader :autotiles
attr_accessor :tone
attr_accessor :color
attr_reader :viewport
attr_accessor :ox # Does nothing
attr_accessor :oy # Does nothing
attr_accessor :visible # Does nothing
attr_reader :viewport
attr_accessor :ox # Does nothing
attr_accessor :oy # Does nothing
attr_accessor :visible # Does nothing
DISPLAY_TILE_WIDTH = Game_Map::TILE_WIDTH rescue 32
DISPLAY_TILE_HEIGHT = Game_Map::TILE_HEIGHT rescue 32
SOURCE_TILE_WIDTH = 32
SOURCE_TILE_HEIGHT = 32
ZOOM_X = DISPLAY_TILE_WIDTH / SOURCE_TILE_WIDTH
ZOOM_Y = DISPLAY_TILE_HEIGHT / SOURCE_TILE_HEIGHT
TILESET_TILES_PER_ROW = 8
AUTOTILES_COUNT = 8 # Counting the blank tile as an autotile
TILES_PER_AUTOTILE = 48
TILESET_START_ID = AUTOTILES_COUNT * TILES_PER_AUTOTILE
DISPLAY_TILE_WIDTH = Game_Map::TILE_WIDTH rescue 32
DISPLAY_TILE_HEIGHT = Game_Map::TILE_HEIGHT rescue 32
SOURCE_TILE_WIDTH = 32
SOURCE_TILE_HEIGHT = 32
ZOOM_X = DISPLAY_TILE_WIDTH / SOURCE_TILE_WIDTH
ZOOM_Y = DISPLAY_TILE_HEIGHT / SOURCE_TILE_HEIGHT
TILESET_TILES_PER_ROW = 8
AUTOTILES_COUNT = 8 # Counting the blank tile as an autotile
TILES_PER_AUTOTILE = 48
TILESET_START_ID = AUTOTILES_COUNT * TILES_PER_AUTOTILE
# If an autotile's filename ends with "[x]", its frame duration will be x/20
# seconds instead.
AUTOTILE_FRAME_DURATION = 5 # In 1/20ths of a second
AUTOTILE_FRAME_DURATION = 5 # In 1/20ths of a second
# Filenames of extra autotiles for each tileset. Each tileset's entry is an
# array containing two other arrays (you can leave either of those empty, but
@@ -38,10 +38,10 @@ class TilemapRenderer
# Extra autotiles are only useful if the tiles are animated, because otherwise
# you just have some tiles which belong in the tileset instead.
EXTRA_AUTOTILES = {
# Examples:
# 1 => [["Sand shore"], ["Flowers2"]],
# 2 => [[], ["Flowers2", "Waterfall", "Waterfall crest", "Waterfall bottom"]],
# 6 => [["Water rock", "Sea deep"], []]
# Examples:
# 1 => [["Sand shore"], ["Flowers2"]],
# 2 => [[], ["Flowers2", "Waterfall", "Waterfall crest", "Waterfall bottom"]],
# 6 => [["Water rock", "Sea deep"], []]
}
#=============================================================================
@@ -52,11 +52,11 @@ class TilemapRenderer
attr_accessor :bitmaps
def initialize
@bitmaps = {}
@bitmap_wraps = {} # Whether each tileset is a mega texture and has multiple columns
@load_counts = {}
@bridge = 0
@changed = true
@bitmaps = {}
@bitmap_wraps = {} # Whether each tileset is a mega texture and has multiple columns
@load_counts = {}
@bridge = 0
@changed = true
end
def [](filename)
@@ -124,10 +124,10 @@ class TilemapRenderer
def initialize
super
@frame_counts = {} # Number of frames in each autotile
@frame_durations = {} # How long each frame lasts per autotile
@current_frames = {} # Which frame each autotile is currently showing
@timer_start = System.uptime
@frame_counts = {} # Number of frames in each autotile
@frame_durations = {} # How long each frame lasts per autotile
@current_frames = {} # Which frame each autotile is currently showing
@timer_start = System.uptime
end
def []=(filename, value)
@@ -137,25 +137,48 @@ class TilemapRenderer
set_current_frame(filename)
end
EXPANDED_AUTOTILES_FOLDER = "Graphics/Autotiles/ExpandedAutotiles/"
def add(filename)
return if nil_or_empty?(filename)
if @bitmaps[filename]
@load_counts[filename] += 1
return
end
orig_bitmap = pbGetAutotile(filename)
@bitmap_wraps[filename] = false
duration = AUTOTILE_FRAME_DURATION
if filename[/\[\s*(\d+?)\s*\]\s*$/]
duration = $~[1].to_i
# Try to load expanded autotile from cache first
cached_path = File.join("Graphics", "Autotiles/ExpandedAutotiles", "#{filename}.png")
if FileTest.exist?(cached_path)
bitmap = RPG::Cache.load_bitmap(EXPANDED_AUTOTILES_FOLDER, filename)
duration = AUTOTILE_FRAME_DURATION
if filename[/\[\s*(\d+?)\s*\]\s*$/]
duration = $~[1].to_i
end
@frame_durations[filename] = duration.to_f / 20
else
orig_bitmap = pbGetAutotile(filename)
@bitmap_wraps[filename] = false
duration = AUTOTILE_FRAME_DURATION
if filename[/\[\s*(\d+?)\s*\]\s*$/]
duration = $~[1].to_i
end
@frame_durations[filename] = duration.to_f / 20
expanded_bitmap = AutotileExpander.expand(orig_bitmap)
# Save expanded bitmap to cache for next time
Dir.mkdir(EXPANDED_AUTOTILES_FOLDER) unless Dir.exist?(EXPANDED_AUTOTILES_FOLDER)
expanded_bitmap.save_to_png(cached_path)
bitmap = expanded_bitmap
orig_bitmap.dispose if orig_bitmap != expanded_bitmap
end
@frame_durations[filename] = duration.to_f / 20
bitmap = AutotileExpander.expand(orig_bitmap)
self[filename] = bitmap
if bitmap.height > SOURCE_TILE_HEIGHT && bitmap.height < TILES_PER_AUTOTILE * SOURCE_TILE_HEIGHT
@bitmap_wraps[filename] = true
end
orig_bitmap.dispose if orig_bitmap != bitmap
@load_counts[filename] = 1
end
@@ -243,57 +266,57 @@ class TilemapRenderer
attr_accessor :need_refresh
def set_bitmap(filename, tile_id, autotile, animated, priority, bitmap)
self.bitmap = bitmap
self.src_rect = Rect.new(0, 0, SOURCE_TILE_WIDTH, SOURCE_TILE_HEIGHT)
self.zoom_x = ZOOM_X
self.zoom_y = ZOOM_Y
@filename = filename
@tile_id = tile_id
@is_autotile = autotile
@animated = animated
@priority = priority
self.bitmap = bitmap
self.src_rect = Rect.new(0, 0, SOURCE_TILE_WIDTH, SOURCE_TILE_HEIGHT)
self.zoom_x = ZOOM_X
self.zoom_y = ZOOM_Y
@filename = filename
@tile_id = tile_id
@is_autotile = autotile
@animated = animated
@priority = priority
@shows_reflection = false
@bridge = false
self.visible = !bitmap.nil?
@need_refresh = true
@bridge = false
self.visible = !bitmap.nil?
@need_refresh = true
end
end
#-----------------------------------------------------------------------------
def initialize(viewport)
@tilesets = TilesetBitmaps.new
@autotiles = AutotileBitmaps.new
@tilesets = TilesetBitmaps.new
@autotiles = AutotileBitmaps.new
@tiles_horizontal_count = (Graphics.width.to_f / DISPLAY_TILE_WIDTH).ceil + 1
@tiles_vertical_count = (Graphics.height.to_f / DISPLAY_TILE_HEIGHT).ceil + 1
@tone = Tone.new(0, 0, 0, 0)
@old_tone = Tone.new(0, 0, 0, 0)
@color = Color.new(0, 0, 0, 0)
@old_color = Color.new(0, 0, 0, 0)
@self_viewport = Viewport.new(0, 0, Graphics.width, Graphics.height)
@viewport = (viewport) ? viewport : @self_viewport
@old_viewport_ox = 0
@old_viewport_oy = 0
@tiles_vertical_count = (Graphics.height.to_f / DISPLAY_TILE_HEIGHT).ceil + 1
@tone = Tone.new(0, 0, 0, 0)
@old_tone = Tone.new(0, 0, 0, 0)
@color = Color.new(0, 0, 0, 0)
@old_color = Color.new(0, 0, 0, 0)
@self_viewport = Viewport.new(0, 0, Graphics.width, Graphics.height)
@viewport = (viewport) ? viewport : @self_viewport
@old_viewport_ox = 0
@old_viewport_oy = 0
# NOTE: The extra tiles horizontally/vertically hang off the left and top
# edges of the screen, because the pixel_offset values are positive
# and are added to the tile sprite coordinates.
@tiles = []
@tiles = []
@tiles_horizontal_count.times do |i|
@tiles[i] = []
@tiles_vertical_count.times do |j|
@tiles[i][j] = Array.new(3) { TileSprite.new(@viewport) }
end
end
@current_map_id = 0
@tile_offset_x = 0
@tile_offset_y = 0
@pixel_offset_x = 0
@pixel_offset_y = 0
@ox = 0
@oy = 0
@visible = true
@need_refresh = true
@disposed = false
@current_map_id = 0
@tile_offset_x = 0
@tile_offset_y = 0
@pixel_offset_x = 0
@pixel_offset_y = 0
@ox = 0
@oy = 0
@visible = true
@need_refresh = true
@disposed = false
end
def dispose
@@ -361,7 +384,7 @@ class TilemapRenderer
if tile_id < TILES_PER_AUTOTILE
tile.set_bitmap("", tile_id, false, false, 0, nil)
tile.shows_reflection = false
tile.bridge = false
tile.bridge = false
else
terrain_tag = map.terrain_tags[tile_id] || 0
terrain_tag_data = GameData::TerrainTag.try_get(terrain_tag)
@@ -378,11 +401,12 @@ class TilemapRenderer
end
if tile_id < true_tileset_start_id
filename = ""
if tile_id < TILESET_START_ID # Real autotiles
if tile_id < TILESET_START_ID # Real autotiles
filename = map.autotile_names[(tile_id / TILES_PER_AUTOTILE) - 1]
elsif tile_id < single_autotile_start_id # Large extra autotiles
elsif tile_id < single_autotile_start_id # Large extra autotiles
filename = extra_autotile_arrays[0][(tile_id - TILESET_START_ID) / TILES_PER_AUTOTILE]
else # Single extra autotiles
else
# Single extra autotiles
filename = extra_autotile_arrays[1][tile_id - single_autotile_start_id]
end
tile.set_bitmap(filename, tile_id, true, @autotiles.animated?(filename),
@@ -392,7 +416,7 @@ class TilemapRenderer
tile.set_bitmap(filename, tile_id, false, false, priority, @tilesets[filename])
end
tile.shows_reflection = terrain_tag_data&.shows_reflections
tile.bridge = terrain_tag_data&.bridge
tile.bridge = terrain_tag_data&.bridge
end
refresh_tile_src_rect(tile, tile_id)
end
@@ -447,7 +471,7 @@ class TilemapRenderer
@tile_offset_x -= offsets[0]
@tile_offset_y -= offsets[1]
else
ret = true # Need a full refresh
ret = true # Need a full refresh
end
else
ret = true
@@ -556,7 +580,7 @@ class TilemapRenderer
@screen_moved_vertically = false
if $PokemonGlobal.bridge != @bridge
@bridge = $PokemonGlobal.bridge
@screen_moved_vertically = true # To update bridge tiles' z values
@screen_moved_vertically = true # To update bridge tiles' z values
end
do_full_refresh = true if check_if_screen_moved
# Update all tile sprites
@@ -609,7 +633,7 @@ class TilemapRenderer
coord.each do |tile|
tile.set_bitmap("", 0, false, false, 0, nil)
tile.shows_reflection = false
tile.bridge = false
tile.bridge = false
end
end
end

View File

@@ -562,7 +562,7 @@ end
# Fades out the screen before a block is run and fades it back in after the
# block exits. z indicates the z-coordinate of the viewport used for this effect
def pbFadeOutIn(z = 99999, nofadeout = false)
duration = 0.4 # In seconds
duration = 0.1 # In seconds
col = Color.new(0, 0, 0, 0)
viewport = Viewport.new(0, 0, Graphics.width, Graphics.height)
viewport.z = z

View File

@@ -5,6 +5,8 @@ class AnimatedBitmap
def initialize(file, hue = 0)
raise "Filename is nil (missing graphic)." if file.nil?
path = file
@path = path
filename = ""
if file.last != "/" # Isn't just a directory
split_file = file.split(/[\\\/]/)
@@ -31,6 +33,8 @@ class AnimatedBitmap
def dispose; @bitmap.dispose; end
def deanimate; @bitmap.deanimate; end
def copy; @bitmap.copy; end
def path; @path end
end
#===============================================================================

View File

@@ -1466,7 +1466,7 @@ module Transitions
@rear_black_sprite.zoom_y = 2.0
@rear_black_sprite.opacity = 192
@rear_black_sprite.visible = false
# Player's bar sprite
# Overrides's bar sprite
@player_bar_x = -BAR_X_INDENT
@player_bar_start_x = @player_bar_x - (@bar_bitmap.width / 2)
@player_bar_y = BAR_Y_INDENT
@@ -1483,7 +1483,7 @@ module Transitions
@foe_bar_sprite.src_rect.x = @bar_bitmap.width / 2
@foe_bar_sprite.src_rect.width = @bar_bitmap.width / 2
@foe_bar_sprite.src_rect.height = BAR_HEIGHT
# Player sprite
# Overrides sprite
@player_sprite = new_sprite(@player_bar_sprite.x + TRAINER_X_OFFSET,
@player_bar_sprite.y + BAR_HEIGHT - TRAINER_Y_OFFSET,
@player_bitmap, @player_bitmap.width / 2, @player_bitmap.height)

View File

@@ -35,7 +35,7 @@ module GameData
return nil if !species || !form
validate species => [Symbol, String]
validate form => Integer
raise _INTL("Undefined species {1}.", species) if !GameData::Species.exists?(species)
#raise _INTL("Undefined species {1}.", species) if !GameData::Species.exists?(species)
species = species.to_sym if species.is_a?(String)
if form > 0
trial = sprintf("%s_%d", species, form).to_sym
@@ -75,7 +75,7 @@ module GameData
def apply_metrics_to_sprite(sprite, index, shadow = false)
if shadow
sprite.x += @shadow_x * 2 if (index & 1) == 1 # Foe Pokémon
elsif (index & 1) == 0 # Player's Pokémon
elsif (index & 1) == 0 # Overrides's Pokémon
sprite.x += @back_sprite[0] * 2
sprite.y += @back_sprite[1] * 2
else # Foe Pokémon

View File

@@ -44,7 +44,7 @@ module GameData
["ID", ReadOnlyProperty, _INTL("ID of this Trainer Type (used as a symbol like :XXX).")],
["Name", StringProperty, _INTL("Name of this Trainer Type as displayed by the game.")],
["Gender", EnumProperty.new(gender_array), _INTL("Gender of this Trainer Type.")],
["BaseMoney", LimitProperty.new(9999), _INTL("Player earns this much money times the highest level among the trainer's Pokémon.")],
["BaseMoney", LimitProperty.new(9999), _INTL("Overrides earns this much money times the highest level among the trainer's Pokémon.")],
["SkillLevel", LimitProperty2.new(9999), _INTL("Skill level of this Trainer Type.")],
["PokeBall", ItemProperty, _INTL("Default Poké Ball that all Pokémon of trainers of this Trainer Type are in.")],
["Flags", StringListProperty, _INTL("Words/phrases that can be used to make trainers of this type behave differently to others.")],

View File

@@ -1,9 +1,9 @@
#===============================================================================
# Results of battle (see module Outcome):
# 0 - Undecided or aborted
# 1 - Player won
# 2 - Player lost
# 3 - Player or wild Pokémon ran from battle, or player forfeited the match
# 1 - Overrides won
# 2 - Overrides lost
# 3 - Overrides or wild Pokémon ran from battle, or player forfeited the match
# 4 - Wild Pokémon was caught
# 5 - Draw
# Possible actions a battler can take in a round:
@@ -43,7 +43,7 @@ class Battle
UNDECIDED = 0
WIN = 1
LOSE = 2 # Also used when player forfeits a trainer battle
FLEE = 3 # Player or wild Pokémon ran away, count as a win
FLEE = 3 # Overrides or wild Pokémon ran away, count as a win
CATCH = 4 # Counts as a win
DRAW = 5
@@ -75,7 +75,7 @@ class Battle
attr_accessor :environment # Battle surroundings (for mechanics purposes)
attr_reader :turnCount
attr_accessor :decision # Outcome of battle
attr_reader :player # Player trainer (or array of trainers)
attr_reader :player # Overrides trainer (or array of trainers)
attr_reader :opponent # Opponent trainer (or array of trainers)
attr_accessor :items # Items held by opponents
attr_accessor :ally_items # Items held by allies
@@ -127,7 +127,7 @@ class Battle
@scene = scene
@peer = Peer.new
@field = ActiveField.new # Whole field (gravity/rooms)
@sides = [ActiveSide.new, # Player's side
@sides = [ActiveSide.new, # Overrides's side
ActiveSide.new] # Foe's side
@positions = [] # Battler positions
@battlers = []
@@ -141,7 +141,7 @@ class Battle
@caughtPokemon = []
player = [player] if !player.nil? && !player.is_a?(Array)
opponent = [opponent] if !opponent.nil? && !opponent.is_a?(Array)
@player = player # Array of Player/NPCTrainer objects, or nil
@player = player # Array of Overrides/NPCTrainer objects, or nil
@opponent = opponent # Array of NPCTrainer objects, or nil
@items = nil
@ally_items = nil # Array of items held by ally. This is just used for Mega Evolution for now.
@@ -288,7 +288,7 @@ class Battle
idxTrainer = pbGetOwnerIndexFromBattlerIndex(idxBattler)
return @opponent[idxTrainer].full_name if opposes?(idxBattler) # Opponent
return @player[idxTrainer].full_name if idxTrainer > 0 # Ally trainer
return @player[idxTrainer].name # Player
return @player[idxTrainer].name # Overrides
end
def pbGetOwnerItems(idxBattler)

View File

@@ -65,7 +65,7 @@ class Battle
if !requireds[i] || requireds[i] == 0
case side
when 0
raise _INTL("Player-side trainer {1} has no battler position for their Pokémon to go (trying {2}v{3} battle)",
raise _INTL("Overrides-side trainer {1} has no battler position for their Pokémon to go (trying {2}v{3} battle)",
i + 1, @sideSizes[0], @sideSizes[1])
when 1
raise _INTL("Opposing trainer {1} has no battler position for their Pokémon to go (trying {2}v{3} battle)",
@@ -74,7 +74,7 @@ class Battle
end
next if requireds[i] <= sideCounts[i] # Trainer has enough Pokémon to fill their positions
if requireds[i] == 1
raise _INTL("Player-side trainer {1} has no able Pokémon", i + 1) if side == 0
raise _INTL("Overrides-side trainer {1} has no able Pokémon", i + 1) if side == 0
raise _INTL("Opposing trainer {1} has no able Pokémon", i + 1) if side == 1
end
# Not enough Pokémon, try lowering the number of battler positions
@@ -393,7 +393,7 @@ class Battle
def pbLoseMoney
return if !@internalBattle || !@moneyGain
return if $game_switches[Settings::NO_MONEY_LOSS]
maxLevel = pbMaxLevelInTeam(0, 0) # Player's Pokémon only, not partner's
maxLevel = pbMaxLevelInTeam(0, 0) # Overrides's Pokémon only, not partner's
multiplier = [8, 16, 24, 36, 48, 64, 80, 100, 120]
idxMultiplier = [pbPlayer.badge_count, multiplier.length - 1].min
tMoney = maxLevel * multiplier[idxMultiplier]
@@ -417,7 +417,7 @@ class Battle
case oldDecision
when Outcome::WIN
PBDebug.log("")
PBDebug.log_header("===== Player won =====")
PBDebug.log_header("===== Overrides won =====")
PBDebug.log("")
if trainerBattle?
@scene.pbTrainerBattleSuccess
@@ -445,8 +445,8 @@ class Battle
@scene.pbShowOpponent(@opponent.length) if trainerBattle? && @caughtPokemon.length > 0
when Outcome::LOSE, Outcome::DRAW
PBDebug.log("")
PBDebug.log_header("===== Player lost =====") if @decision == Outcome::LOSE
PBDebug.log_header("===== Player drew with opponent =====") if @decision == Outcome::DRAW
PBDebug.log_header("===== Overrides lost =====") if @decision == Outcome::LOSE
PBDebug.log_header("===== Overrides drew with opponent =====") if @decision == Outcome::DRAW
PBDebug.log("")
if @internalBattle
if pbPlayerBattlerCount == 0

View File

@@ -186,11 +186,11 @@ class Battle
end
pbRecallAndReplace(idxBattler, idxPartyNew)
switched.push(idxBattler)
elsif trainerBattle? # Player switches in in a trainer battle
elsif trainerBattle? # Overrides switches in in a trainer battle
idxPlayerPartyNew = pbGetReplacementPokemonIndex(idxBattler) # Owner chooses
pbRecallAndReplace(idxBattler, idxPlayerPartyNew)
switched.push(idxBattler)
else # Player's Pokémon has fainted in a wild battle
else # Overrides's Pokémon has fainted in a wild battle
switch = false
if pbDisplayConfirm(_INTL("Use next Pokémon?"))
switch = true

View File

@@ -194,7 +194,7 @@ class Battle
end
end
# Choose actions for the round (player first, then AI)
pbCommandPhaseLoop(true) # Player chooses their actions
pbCommandPhaseLoop(true) # Overrides chooses their actions
if decided? # Battle ended, stop choosing actions
@command_phase = false
return
@@ -223,7 +223,7 @@ class Battle
@battleAI.pbDefaultChooseEnemyCommand(idxBattler)
next
end
# Player chooses an action
# Overrides chooses an action
actioned.push(idxBattler)
commandsEnd = false # Whether to cancel choosing all other actions this round
loop do

View File

@@ -55,7 +55,7 @@ class Battle::Scene
partyBar = pbAddSprite("partyBar_#{side}", 0, 0,
"Graphics/UI/Battle/overlay_lineup", @viewport)
partyBar.z = 10120
partyBar.mirror = true if side == 0 # Player's lineup bar only
partyBar.mirror = true if side == 0 # Overrides's lineup bar only
partyBar.visible = false
NUM_BALLS.times do |i|
ball = pbAddSprite("partyBall_#{side}_#{i}", 0, 0, nil, @viewport)
@@ -67,7 +67,7 @@ class Battle::Scene
@sprites["abilityBar_#{side}"] = AbilitySplashBar.new(side, @viewport)
end
end
# Player's and partner trainer's back sprite
# Overrides's and partner trainer's back sprite
@battle.player.each_with_index do |p, i|
pbCreateTrainerBackSprite(i, p.trainer_type, @battle.player.length)
end
@@ -155,7 +155,7 @@ class Battle::Scene
end
def pbCreateTrainerBackSprite(idxTrainer, trainerType, numTrainers = 1)
if idxTrainer == 0 # Player's sprite
if idxTrainer == 0 # Overrides's sprite
trainerFile = GameData::TrainerType.player_back_sprite_filename(trainerType)
else # Partner trainer's sprite
trainerFile = GameData::TrainerType.back_sprite_filename(trainerType)

View File

@@ -17,7 +17,7 @@ class Battle::Scene::Animation::Intro < Battle::Scene::Animation
# Bases
makeSlideSprite("base_0", 1, appearTime, PictureOrigin::BOTTOM)
makeSlideSprite("base_1", -1, appearTime, PictureOrigin::CENTER)
# Player sprite, partner trainer sprite
# Overrides sprite, partner trainer sprite
@battle.player.each_with_index do |_p, i|
makeSlideSprite("player_#{i + 1}", 1, appearTime, PictureOrigin::BOTTOM)
end
@@ -96,7 +96,7 @@ class Battle::Scene::Animation::LineupAppear < Battle::Scene::Animation
def resetGraphics(sprites)
bar = sprites["partyBar_#{@side}"]
case @side
when 0 # Player's lineup
when 0 # Overrides's lineup
barX = Graphics.width - BAR_DISPLAY_WIDTH
barY = Graphics.height - 142
ballX = barX + 44
@@ -124,7 +124,7 @@ class Battle::Scene::Animation::LineupAppear < Battle::Scene::Animation
end
def getPartyIndexFromBallIndex(idxBall)
# Player's lineup (just show balls for player's party)
# Overrides's lineup (just show balls for player's party)
if @side == 0
return idxBall if @partyStarts.length < 2
return idxBall if idxBall < @partyStarts[1]

View File

@@ -201,7 +201,7 @@ class Battle::Scene::Animation::ThrowRock < Battle::Scene::Animation
# Show anger appearing
delay = ball.totalDuration + 5
2.times do
anger.setSE(delay, "Player jump")
anger.setSE(delay, "Overrides jump")
anger.setVisible(delay, true)
anger.moveZoom(delay, 3, 130)
anger.moveZoom(delay + 3, 3, 100)

View File

@@ -271,7 +271,7 @@ module RecordedBattle::PlaybackHelper
return nil if !trainer
ret = []
trainer.each do |tr|
if tr.length == 4 # Player
if tr.length == 4 # Overrides
t = Player.new(tr[1], tr[0])
t.badges = tr[3]
else # NPCTrainer

View File

@@ -566,7 +566,7 @@ def pbWait(duration)
end
#===============================================================================
# Player/event movement in the field.
# Overrides/event movement in the field.
#===============================================================================
def pbSlideOnIce
if !$DEBUG || !Input.press?(Input::CTRL)

View File

@@ -324,9 +324,9 @@ module BattleCreationHelperMethods
# Save the result of the battle in a Game Variable (1 by default)
# 0 - Undecided or aborted
# 1 - Player won
# 2 - Player lost
# 3 - Player or wild Pokémon ran from battle, or player forfeited the match
# 1 - Overrides won
# 2 - Overrides lost
# 3 - Overrides or wild Pokémon ran from battle, or player forfeited the match
# 4 - Wild Pokémon was caught
# 5 - Draw
def set_outcome(outcome, outcome_variable = 1, trainer_battle = false)

View File

@@ -11,7 +11,7 @@ class PokemonGlobalMetadata
attr_accessor :descending_waterfall
attr_accessor :ascending_waterfall
attr_accessor :fishing
# Player data
# Overrides data
attr_accessor :startTime
attr_accessor :stepcount
attr_accessor :pcItemStorage
@@ -64,7 +64,7 @@ class PokemonGlobalMetadata
@descending_waterfall = false
@ascending_waterfall = false
@fishing = false
# Player data
# Overrides data
@startTime = Time.now
@stepcount = 0
@pcItemStorage = nil

View File

@@ -23,7 +23,7 @@ class PokemonEvolutionScene
def pbStartScreen(pokemon, newspecies)
@pokemon = pokemon
@newspecies = newspecies
@fused_pokemon_dex_number = newspecies
@sprites = {}
@bgviewport = Viewport.new(0, 0, Graphics.width, Graphics.height)
@bgviewport.z = 99999
@@ -40,7 +40,7 @@ class PokemonEvolutionScene
rsprite1.y = (Graphics.height - 64) / 2
rsprite2 = PokemonSprite.new(@viewport)
rsprite2.setOffset(PictureOrigin::CENTER)
rsprite2.setPokemonBitmapSpecies(@pokemon, @newspecies, false)
rsprite2.setPokemonBitmapSpecies(@pokemon, @fused_pokemon_dex_number, false)
rsprite2.x = rsprite1.x
rsprite2.y = rsprite1.y
rsprite2.visible = false
@@ -197,8 +197,8 @@ class PokemonEvolutionScene
def pbEvolutionSuccess
$stats.evolution_count += 1
# Play cry of evolved species
cry_time = GameData::Species.cry_length(@newspecies, @pokemon.form)
Pokemon.play_cry(@newspecies, @pokemon.form)
cry_time = GameData::Species.cry_length(@fused_pokemon_dex_number, @pokemon.form)
Pokemon.play_cry(@fused_pokemon_dex_number, @pokemon.form)
timer_start = System.uptime
loop do
Graphics.update
@@ -208,7 +208,7 @@ class PokemonEvolutionScene
pbBGMStop
# Success jingle/message
pbMEPlay("Evolution success")
newspeciesname = GameData::Species.get(@newspecies).name
newspeciesname = GameData::Species.get(@fused_pokemon_dex_number).name
pbMessageDisplay(@sprites["msgwindow"],
"\\se[]" + _INTL("Congratulations! Your {1} evolved into {2}!",
@pokemon.name, newspeciesname) + "\\wt[80]") { pbUpdate }
@@ -217,14 +217,14 @@ class PokemonEvolutionScene
pbEvolutionMethodAfterEvolution
# Modify Pokémon to make it evolved
was_fainted = @pokemon.fainted?
@pokemon.species = @newspecies
@pokemon.species = @fused_pokemon_dex_number
@pokemon.hp = 0 if was_fainted
@pokemon.calc_stats
@pokemon.ready_to_evolve = false
# See and own evolved species
was_owned = $player.owned?(@newspecies)
was_owned = $player.owned?(@fused_pokemon_dex_number)
$player.pokedex.register(@pokemon)
$player.pokedex.set_owned(@newspecies)
$player.pokedex.set_owned(@fused_pokemon_dex_number)
moves_to_learn = []
movelist = @pokemon.getMoveList
movelist.each do |i|
@@ -252,7 +252,7 @@ class PokemonEvolutionScene
end
def pbEvolutionMethodAfterEvolution
@pokemon.action_after_evolution(@newspecies)
@pokemon.action_after_evolution(@fused_pokemon_dex_number)
end
def pbUpdate(animating = false)

View File

@@ -116,7 +116,7 @@ class PokemonEntryScene
@sprites["helpwindow"].shadowColor = Color.new(168, 184, 184)
addBackgroundPlane(@sprites, "background", "Naming/bg_2", @viewport)
case subject
when 1 # Player
when 1 # Overrides
meta = GameData::PlayerMetadata.get($player.character_ID)
if meta
@sprites["shadow"] = IconSprite.new(0, 0, @viewport)
@@ -397,7 +397,7 @@ class PokemonEntryScene2
@sprites["bg"] = IconSprite.new(0, 0, @viewport)
@sprites["bg"].setBitmap("Graphics/UI/Naming/bg")
case subject
when 1 # Player
when 1 # Overrides
meta = GameData::PlayerMetadata.get($player.character_ID)
if meta
@sprites["shadow"] = IconSprite.new(0, 0, @viewport)

View File

@@ -115,7 +115,7 @@ class UI::TownMapVisuals < UI::BaseVisuals
create_pin(key, @pins_pos[key][0], @pins_pos[key][1], graphics_folder + roamer[:icon], 80)
end
end
# Player's head showing their current location
# Overrides's head showing their current location
if !@pins_pos[:player]
create_pin(:player, 0, 0, GameData::TrainerType.player_map_icon_filename($player.trainer_type), 100)
end
@@ -403,7 +403,7 @@ class UI::TownMapVisuals < UI::BaseVisuals
def update_pin_positions_while_zooming
@sprites[:cursor].x, @sprites[:cursor].y = point_to_screen(@cursor_pos[:x], @cursor_pos[:y])
# Player, roamers, markings
# Overrides, roamers, markings
@pins_pos.each_pair do |key, pos|
@sprites[key].x, @sprites[key].y = point_to_screen(*pos)
end

View File

@@ -15,8 +15,9 @@ class UI::TrainerCardVisuals < UI::BaseVisuals
def initialize_sprites
# Trainer card
add_icon_sprite(:card, 0, 0, graphics_folder + gendered_filename(_INTL("trainer_card")))
# Player sprite (coordinates are the bottom middle of the sprite)
add_icon_sprite(:player, 400, 240, GameData::TrainerType.player_front_sprite_filename($player.trainer_type))
# Overrides sprite (coordinates are the bottom middle of the sprite)
@sprites[:player] = IconSprite.new(400, 240, @viewport)
@sprites[:player].setBitmapDirectly(generate_front_trainer_sprite_bitmap())
if !@sprites[:player].bitmap
raise _INTL("No trainer front sprite exists for the player character, expected a file at {1}.",
"Graphics/Trainers/" + $player.trainer_type.to_s + ".png")

View File

@@ -146,7 +146,7 @@ class UI::LoadContinuePanel < UI::LoadPanel
filename = pbGetPlayerCharset(meta.walk_charset, @save_data[:player], true)
@sprites[:player] = TrainerWalkingCharSprite.new(filename, @viewport)
if !@sprites[:player].bitmap
raise _INTL("Player character {1}'s walking charset was not found (filename: \"{2}\").",
raise _INTL("Overrides character {1}'s walking charset was not found (filename: \"{2}\").",
@save_data[:player].character_ID, filename)
end
@sprites[:player].x = 48 - (@sprites[:player].bitmap.width / 8)
@@ -223,7 +223,7 @@ class UI::LoadContinuePanel < UI::LoadPanel
filename = pbGetPlayerCharset(meta.walk_charset, @save_data[:player], true)
@sprites[:player].charset = filename
if !@sprites[:player].bitmap
raise _INTL("Player character {1}'s walking charset was not found (filename: \"{2}\").",
raise _INTL("Overrides character {1}'s walking charset was not found (filename: \"{2}\").",
@save_data[:player].character_ID, filename)
end
end
@@ -255,7 +255,7 @@ class UI::LoadContinuePanel < UI::LoadPanel
elsif @save_data[:player].female?
gender_theme = :female
end
# Player's name
# Overrides's name
draw_text(@save_data[:player].name, 78, 66, theme: gender_theme)
# Location
map_id = @save_data[:map_factory].map.map_id

View File

@@ -48,7 +48,7 @@ class UI::SavePanel < UI::SpriteContainer
filename = pbGetPlayerCharset(meta.walk_charset, @save_data[:player], true)
@sprites[:player] = TrainerWalkingCharSprite.new(filename, @viewport)
if !@sprites[:player].bitmap
raise _INTL("Player character {1}'s walking charset was not found (filename: \"{2}\").",
raise _INTL("Overrides character {1}'s walking charset was not found (filename: \"{2}\").",
@save_data[:player].character_ID, filename)
end
@sprites[:player].x = 44 - (@sprites[:player].bitmap.width / 8)
@@ -130,7 +130,7 @@ class UI::SavePanel < UI::SpriteContainer
filename = pbGetPlayerCharset(meta.walk_charset, @save_data[:player], true)
@sprites[:player].charset = filename
if !@sprites[:player].bitmap
raise _INTL("Player character {1}'s walking charset was not found (filename: \"{2}\").",
raise _INTL("Overrides character {1}'s walking charset was not found (filename: \"{2}\").",
@save_data[:player].character_ID, filename)
end
end
@@ -165,7 +165,7 @@ class UI::SavePanel < UI::SpriteContainer
elsif @save_data[:player].female?
gender_theme = :female
end
# Player's name
# Overrides's name
draw_text(@save_data[:player].name, 78, 30, theme: gender_theme)
# Location
map_id = @save_data[:map_factory].map.map_id

View File

@@ -171,7 +171,7 @@ class PokemonLoad_Scene
filename = pbGetPlayerCharset(meta.walk_charset, trainer, true)
@sprites["player"] = TrainerWalkingCharSprite.new(filename, @viewport)
if !@sprites["player"].bitmap
raise _INTL("Player character {1}'s walking charset was not found (filename: \"{2}\").", trainer.character_ID, filename)
raise _INTL("Overrides character {1}'s walking charset was not found (filename: \"{2}\").", trainer.character_ID, filename)
end
charwidth = @sprites["player"].bitmap.width
charheight = @sprites["player"].bitmap.height

View File

@@ -29,7 +29,7 @@ class PokemonSave_Scene
end
location_tag = shadowc3tag(LOCATION_TEXT_BASE, LOCATION_TEXT_SHADOW)
loctext = location_tag + "<ac>" + mapname + "</ac></c3>"
loctext += _INTL("Player") + "<r>" + text_tag + $player.name + "</c3><br>"
loctext += _INTL("Overrides") + "<r>" + text_tag + $player.name + "</c3><br>"
if hour > 0
loctext += _INTL("Time") + "<r>" + text_tag + _INTL("{1}h {2}m", hour, min) + "</c3><br>"
else

View File

@@ -249,7 +249,7 @@ class PokemonDuel
pbMoveRoute(event, [PBMoveRoute::FORWARD])
pbMoveRoute($game_player, [PBMoveRoute::FORWARD])
@hp[0] -= action # Enemy action
@hp[1] -= command # Player command
@hp[1] -= command # Overrides command
pbMessage(_INTL("You hit each other!"))
elsif action == 2 && command == 0
pbMoveRoute(event,

View File

@@ -107,7 +107,7 @@ class TriadCard
bitmap = Bitmap.new(80, 96)
if owner == 2 # Opponent
cardbitmap = AnimatedBitmap.new("Graphics/UI/Triple Triad/card_opponent")
else # Player
else # Overrides
cardbitmap = AnimatedBitmap.new("Graphics/UI/Triple Triad/card_player")
end
typebitmap = AnimatedBitmap.new(_INTL("Graphics/UI/types"))
@@ -811,7 +811,7 @@ class TriadScreen
triadCard = nil
cardIndex = 0
if playerTurn
# Player's turn
# Overrides's turn
until position
cardIndex = @scene.pbPlayerChooseCard(cards.length)
triadCard = TriadCard.new(cards[cardIndex])

View File

@@ -146,8 +146,8 @@ def pbSafariBattle(pkmn, level = 1)
end
# Save the result of the battle in Game Variable 1
# 0 - Undecided or aborted
# 2 - Player ran out of Safari Balls
# 3 - Player or wild Pokémon ran from battle, or player forfeited the match
# 2 - Overrides ran out of Safari Balls
# 3 - Overrides or wild Pokémon ran from battle, or player forfeited the match
# 4 - Wild Pokémon was caught
if outcome == Battle::Outcome::CATCH
$stats.safari_pokemon_caught += 1

View File

@@ -222,7 +222,7 @@ def pbNoticePlayer(event, always_show_exclaim = false)
end
#===============================================================================
# Player-related utilities, random name generator.
# Overrides-related utilities, random name generator.
#===============================================================================
# Unused
def pbGetPlayerGraphic

View File

@@ -77,7 +77,7 @@ def pbPlayTrainerIntroBGM(trainer_type)
pbBGMPlay(bgm)
end
# Can be a Player, NPCTrainer or an array of them.
# Can be a Overrides, NPCTrainer or an array of them.
def pbGetTrainerBattleBGM(trainer)
return $PokemonGlobal.nextBattleBGM.clone if $PokemonGlobal.nextBattleBGM
ret = nil
@@ -120,7 +120,7 @@ def pbGetTrainerBattleBGMFromType(trainertype)
return ret
end
# Can be a Player, NPCTrainer or an array of them.
# Can be a Overrides, NPCTrainer or an array of them.
def pbGetTrainerVictoryBGM(trainer)
if $PokemonGlobal.nextBattleVictoryBGM
return $PokemonGlobal.nextBattleVictoryBGM.clone

View File

@@ -753,7 +753,7 @@ def pbEditPlayerMetadata(player_id = 1)
val = property[1].defaultValue if val.nil? && property[1].respond_to?(:defaultValue)
data.push(val)
end
if pbPropertyList(_INTL("Player {1}", metadata.id), data, properties, true)
if pbPropertyList(_INTL("Overrides {1}", metadata.id), data, properties, true)
# Construct player metadata hash
schema = GameData::PlayerMetadata.schema
metadata_hash = {}

View File

@@ -21,7 +21,7 @@ def pbAutoPositionAll
metrics = GameData::SpeciesMetrics.get_species_form(sp.species, sp.form)
bitmap1 = GameData::Species.sprite_bitmap(sp.species, sp.form, nil, nil, nil, true)
bitmap2 = GameData::Species.sprite_bitmap(sp.species, sp.form)
if bitmap1&.bitmap # Player's y
if bitmap1&.bitmap # Overrides's y
metrics.back_sprite[0] = 0
metrics.back_sprite[1] = (bitmap1.height - (findBottom(bitmap1.bitmap) + 1)) / 2
end

View File

@@ -842,11 +842,11 @@ MenuHandlers.add(:debug_menu, :empty_bag, {
})
#===============================================================================
# Player options.
# Overrides options.
#===============================================================================
MenuHandlers.add(:debug_menu, :player_menu, {
"name" => _INTL("Player options..."),
"name" => _INTL("Overrides options..."),
"parent" => :main,
"description" => _INTL("Set money, badges, Pokédexes, player's appearance and name, etc."),
"always_show" => false
@@ -1114,7 +1114,7 @@ MenuHandlers.add(:debug_menu, :change_outfit, {
params.setRange(0, 99)
params.setDefaultValue(oldoutfit)
$player.outfit = pbMessageChooseNumber(_INTL("Set the player's outfit."), params)
pbMessage(_INTL("Player's outfit was changed.")) if $player.outfit != oldoutfit
pbMessage(_INTL("Overrides's outfit was changed.")) if $player.outfit != oldoutfit
}
})

View File

@@ -9,7 +9,7 @@ MenuHandlers.add(:battle_debug_menu, :battlers, {
})
MenuHandlers.add(:battle_debug_menu, :list_player_battlers, {
"name" => _INTL("Player-side battlers"),
"name" => _INTL("Overrides-side battlers"),
"parent" => :battlers,
"description" => _INTL("Edit Pokémon on the player's side of battle."),
"effect" => proc { |battle|
@@ -103,7 +103,7 @@ MenuHandlers.add(:battle_debug_menu, :pokemon_teams, {
first_index = player_party_starts[i]
last_index = (i < player_party_starts.length - 1) ? player_party_starts[i + 1] : battle.pbParty(0).length
num_pkmn = last_index - first_index
if i == 0 # Player
if i == 0 # Overrides
commands.push(_INTL("You: {1} ({2} Pokémon)", trainer.full_name, num_pkmn))
else
commands.push(_INTL("Ally {1}: {2} ({3} Pokémon)", i, trainer.full_name, num_pkmn))
@@ -162,7 +162,7 @@ MenuHandlers.add(:battle_debug_menu, :trainer_items, {
end
if battle.player.length > 1
battle.player.each_with_index do |trainer, i|
next if i == 0 # Player
next if i == 0 # Overrides
items = battle.ally_items ? battle.ally_items[i].clone : []
commands.push(_INTL("Ally {1}: {2} ({3} items)", i, trainer.full_name, items.length))
item_arrays.push(items)
@@ -436,7 +436,7 @@ MenuHandlers.add(:battle_debug_menu, :set_field_effects, {
})
MenuHandlers.add(:battle_debug_menu, :player_side, {
"name" => _INTL("Player's side effects..."),
"name" => _INTL("Overrides's side effects..."),
"parent" => :field,
"description" => _INTL("Effects that apply to the side the player is on."),
"effect" => proc { |battle|

View File

@@ -920,7 +920,7 @@ MenuHandlers.add(:pokemon_debug_menu, :ownership, {
gender_text = _INTL("Male") if pkmn.owner.male?
gender_text = _INTL("Female") if pkmn.owner.female?
public_id_text = sprintf("%05d", pkmn.owner.public_id)
msg = [_INTL("Player's Pokémon\n{1}\n{2}\n{3} ({4})",
msg = [_INTL("Overrides's Pokémon\n{1}\n{2}\n{3} ({4})",
pkmn.owner.name, gender_text, public_id_text, pkmn.owner.id),
_INTL("Foreign Pokémon\n{1}\n{2}\n{3} ({4})",
pkmn.owner.name, gender_text, public_id_text, pkmn.owner.id)][pkmn.foreign?($player) ? 1 : 0]

View File

@@ -269,7 +269,7 @@ class MetadataLister
def commands
@commands.clear
@commands.push(_INTL("[GLOBAL METADATA]"))
@player_ids.each { |id| @commands.push(_INTL("Player {1}", id)) }
@player_ids.each { |id| @commands.push(_INTL("Overrides {1}", id)) }
@commands.push(_INTL("[ADD NEW PLAYER]")) if @new_player
return @commands
end
@@ -277,7 +277,7 @@ class MetadataLister
# Cancel: -1
# New player: -2
# Global metadata: 0
# Player character: 1+ (the player ID itself)
# Overrides character: 1+ (the player ID itself)
def value(index)
return index if index < 1
return -2 if @new_player && index == @commands.length - 1

View File

@@ -1344,7 +1344,7 @@ module Compiler
else
validate_compiled_player_metadata(data_hash)
if GameData::PlayerMetadata.exists?(data_hash[:id])
raise _INTL("Player metadata ID '{1}' is used twice.", data_hash[:id]) + "\n" + FileLineData.linereport
raise _INTL("Overrides metadata ID '{1}' is used twice.", data_hash[:id]) + "\n" + FileLineData.linereport
end
end
# Add section's data to records

View File

@@ -20,7 +20,7 @@ module Compiler
["pbCanStore?", "$bag.can_add?"],
["pbStoreItem", "$bag.add"],
["pbStoreAllOrNone", "$bag.add_all"],
["$Trainer", "$player"],
["$player", "$player"],
["$SaveVersion", "$save_engine_version"],
["$game_version", "$save_game_version"],
["$MapFactory", "$map_factory"],
@@ -880,12 +880,12 @@ module Compiler
changed = true
end
# If the last page's Switch condition uses a Switch named 's:tsOff?("A")',
# check the penultimate page. If it contains exactly 1 "Transfer Player"
# check the penultimate page. If it contains exactly 1 "Transfer Overrides"
# command and does NOT contain a "Change Transparent Flag" command, rewrite
# both the penultimate page and the last page.
if mapData.switchName(lastPage.condition.switch1_id) == 's:tsOff?("A")'
list = event.pages[event.pages.length - 2].list
transferCommand = list.find_all { |cmd| cmd.code == 201 } # Transfer Player
transferCommand = list.find_all { |cmd| cmd.code == 201 } # Transfer Overrides
if transferCommand.length == 1 && list.none? { |cmd| cmd.code == 208 } # Change Transparent Flag
# Rewrite penultimate page
list.clear
@@ -913,7 +913,7 @@ module Compiler
push_event(list, 223, [Tone.new(-255, -255, -255), 6]) # Change Screen Color Tone
push_wait(list, 8) # Wait
push_event(list, 208, [1]) # Change Transparent Flag (visible)
push_event(list, transferCommand[0].code, transferCommand[0].parameters) # Transfer Player
push_event(list, transferCommand[0].code, transferCommand[0].parameters) # Transfer Overrides
push_event(list, 223, [Tone.new(0, 0, 0), 6]) # Change Screen Color Tone
push_end(list)
# Rewrite last page
@@ -957,7 +957,7 @@ module Compiler
end
# Checks if the event has exactly 1 page, said page has no graphic, it has
# less than 12 commands and at least one is a Transfer Player, and the tiles
# less than 12 commands and at least one is a Transfer Overrides, and the tiles
# to the left/right/upper left/upper right are not passable but the event's
# tile is. Causes a second page to be added to the event which is the "is
# player on me?" check that occurs when the map is entered.
@@ -966,7 +966,7 @@ module Compiler
return false if thisEvent.pages.length != 1
if thisEvent.pages[0].graphic.character_name == "" &&
thisEvent.pages[0].list.length <= 12 &&
thisEvent.pages[0].list.any? { |cmd| cmd.code == 201 } && # Transfer Player
thisEvent.pages[0].list.any? { |cmd| cmd.code == 201 } && # Transfer Overrides
# mapData.isPassable?(mapID, thisEvent.x, thisEvent.y + 1) &&
mapData.isPassable?(mapID, thisEvent.x, thisEvent.y) &&
!mapData.isPassable?(mapID, thisEvent.x - 1, thisEvent.y) &&
@@ -1272,12 +1272,12 @@ module Compiler
list.delete_at(i)
changed = true
end
when 201 # Transfer Player
when 201 # Transfer Overrides
if list.length <= 8
=begin
if params[0]==0
# Look for another event just above the position this Transfer
# Player command will transfer to - it may be a door, in which case
# Overrides command will transfer to - it may be a door, in which case
# this command should transfer the player onto the door instead of
# in front of it.
e = mapData.getEventFromXY(params[1],params[2],params[3]-1)
@@ -1295,7 +1295,7 @@ module Compiler
mapData.saveMap(params[1])
changed = true
end
# Checks if the found event is a simple Transfer Player one nestled
# Checks if the found event is a simple Transfer Overrides one nestled
# between tiles that aren't passable - it is likely a door, so give
# it a second page with an "is player on me?" check.
if likely_passage?(e,params[1],mapData) # Checks the first page
@@ -1339,30 +1339,30 @@ module Compiler
# If the next event command is a Move Route that moves the player,
# check whether all it does is turn the player in a direction (or
# its first item is to move the player in a direction). If so, this
# Transfer Player command may as well set the player's direction
# Transfer Overrides command may as well set the player's direction
# instead; make it do so and delete that Move Route.
if params[4]==0 && # Retain direction
i+1<list.length && list[i+1].code==209 && list[i+1].parameters[0]==-1 # Set Move Route
route = list[i+1].parameters[1]
if route && route.list.length<=2
# Delete superfluous move route command if necessary
if route.list[0].code==16 # Player Turn Down
if route.list[0].code==16 # Overrides Turn Down
deleteMoveRouteAt.call(list,i+1)
params[4] = 2
changed = true
elsif route.list[0].code==17 # Player Turn Left
elsif route.list[0].code==17 # Overrides Turn Left
deleteMoveRouteAt.call(list,i+1)
params[4] = 4
changed = true
elsif route.list[0].code==18 # Player Turn Right
elsif route.list[0].code==18 # Overrides Turn Right
deleteMoveRouteAt.call(list,i+1)
params[4] = 6
changed = true
elsif route.list[0].code==19 # Player Turn Up
elsif route.list[0].code==19 # Overrides Turn Up
deleteMoveRouteAt.call(list,i+1)
params[4] = 8
changed = true
elsif (route.list[0].code==1 || route.list[0].code==2 || # Player Move (4-dir)
elsif (route.list[0].code==1 || route.list[0].code==2 || # Overrides Move (4-dir)
route.list[0].code==3 || route.list[0].code==4) && list.length==4
params[4] = [0,2,4,6,8][route.list[0].code]
deletedRoute = deleteMoveRouteAt.call(list,i+1)
@@ -1370,10 +1370,10 @@ module Compiler
end
end
# If an event command before this one is a Move Route that just
# turns the player, delete it and make this Transfer Player command
# turns the player, delete it and make this Transfer Overrides command
# set the player's direction instead.
# (I don't know if it makes sense to do this, as there could be a
# lot of commands between then and this Transfer Player which this
# lot of commands between then and this Transfer Overrides which this
# code can't recognise and deal with, so I've quoted this code out.)
elsif params[4]==0 && i>3 # Retain direction
# for j in 0...i
@@ -1382,22 +1382,22 @@ module Compiler
# if route && route.list.length<=2
# oldlistlength = list.length
# # Delete superfluous move route command if necessary
# if route.list[0].code==16 # Player Turn Down
# if route.list[0].code==16 # Overrides Turn Down
# deleteMoveRouteAt.call(list,j)
# params[4] = 2
# changed = true
# i -= (oldlistlength-list.length)
# elsif route.list[0].code==17 # Player Turn Left
# elsif route.list[0].code==17 # Overrides Turn Left
# deleteMoveRouteAt.call(list,j)
# params[4] = 4
# changed = true
# i -= (oldlistlength-list.length)
# elsif route.list[0].code==18 # Player Turn Right
# elsif route.list[0].code==18 # Overrides Turn Right
# deleteMoveRouteAt.call(list,j)
# params[4] = 6
# changed = true
# i -= (oldlistlength-list.length)
# elsif route.list[0].code==19 # Player Turn Up
# elsif route.list[0].code==19 # Overrides Turn Up
# deleteMoveRouteAt.call(list,j)
# params[4] = 8
# changed = true
@@ -1408,7 +1408,7 @@ module Compiler
# end
# If the next event command changes the screen color, and the one
# after that is a Move Route which only turns the player in a
# direction, this Transfer Player command may as well set the
# direction, this Transfer Overrides command may as well set the
# player's direction instead; make it do so and delete that Move
# Route.
elsif params[4]==0 && # Retain direction
@@ -1419,19 +1419,19 @@ module Compiler
route = list[i+2].parameters[1]
if route && route.list.length<=2
# Delete superfluous move route command if necessary
if route.list[0].code==16 # Player Turn Down
if route.list[0].code==16 # Overrides Turn Down
deleteMoveRouteAt.call(list,i+2)
params[4] = 2
changed = true
elsif route.list[0].code==17 # Player Turn Left
elsif route.list[0].code==17 # Overrides Turn Left
deleteMoveRouteAt.call(list,i+2)
params[4] = 4
changed = true
elsif route.list[0].code==18 # Player Turn Right
elsif route.list[0].code==18 # Overrides Turn Right
deleteMoveRouteAt.call(list,i+2)
params[4] = 6
changed = true
elsif route.list[0].code==19 # Player Turn Up
elsif route.list[0].code==19 # Overrides Turn Up
deleteMoveRouteAt.call(list,i+2)
params[4] = 8
changed = true

View File

@@ -9,7 +9,7 @@ class AnimationEditor
else
@settings = {
:color_scheme => :light,
:side_sizes => [1, 1], # Player's side, opposing side
:side_sizes => [1, 1], # Overrides's side, opposing side
:user_index => 0, # 0, 2, 4
:target_indices => [1], # There must be at least one valid target
:user_opposes => false,

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,17 @@
# frozen_string_literal: true
class Game_Temp
attr_accessor :unimportedSprites
attr_accessor :nb_imported_sprites
attr_accessor :loading_screen
attr_accessor :custom_sprites_list
attr_accessor :base_sprites_list
attr_accessor :forced_alt_sprites
alias pokemonEssentials_GameTemp_original_initialize initialize
def initialize
pokemonEssentials_GameTemp_original_initialize
@custom_sprites_list ={}
@base_sprites_list ={}
end
end

View File

@@ -0,0 +1,794 @@
#===============================================================================
# Abstraction layer for Pokemon Essentials
#===============================================================================
class PokemonMartAdapter
def getMoney
return $player.money
end
def getMoneyString
return pbGetGoldString
end
def setMoney(value)
$player.money = value
end
def getInventory
return $PokemonBag
end
def getName(item)
return GameData::Item.get(item).name
end
def getDisplayName(item)
item_name = getName(item)
if GameData::Item.get(item).is_machine?
machine = GameData::Item.get(item).move
item_name = _INTL("{1} {2}", item_name, GameData::Move.get(machine).name)
end
return item_name
end
def getDescription(item)
return GameData::Item.get(item).description
end
def getItemIcon(item)
return (item) ? GameData::Item.icon_filename(item) : nil
end
# Unused
def getItemIconRect(_item)
return Rect.new(0, 0, 48, 48)
end
def getQuantity(item)
return $PokemonBag.pbQuantity(item)
end
def showQuantity?(item)
return !GameData::Item.get(item).is_important?
end
def getPrice(item, selling = false)
if $game_temp.mart_prices && $game_temp.mart_prices[item]
if selling
return $game_temp.mart_prices[item][1] if $game_temp.mart_prices[item][1] >= 0
else
return $game_temp.mart_prices[item][0] if $game_temp.mart_prices[item][0] > 0
end
end
return GameData::Item.get(item).price
end
def getDisplayPrice(item, selling = false)
price = getPrice(item, selling).to_s_formatted
return _INTL("$ {1}", price)
end
def canSell?(item)
return getPrice(item, true) > 0 && !GameData::Item.get(item).is_important?
end
def addItem(item)
return $PokemonBag.pbStoreItem(item)
end
def removeItem(item)
return $PokemonBag.pbDeleteItem(item)
end
def getBaseColorOverride(item)
return nil
end
def getShadowColorOverride(item)
return nil
end
#specialType is a symbol
def getSpecialItemCaption(specialType)
return nil
end
def getSpecialItemDescription(specialType)
return nil
end
def doSpecialItemAction(specialType,itemId=nil)
return nil
end
def getSpecialItemBaseColor(specialType)
return nil
end
def getSpecialItemShadowColor(specialType)
return nil
end
end
#===============================================================================
# Buy and Sell adapters
#===============================================================================
class BuyAdapter
def initialize(adapter)
@adapter = adapter
end
def getDisplayName(item)
@adapter.getDisplayName(item)
end
def getDisplayPrice(item)
@adapter.getDisplayPrice(item, false)
end
def getBaseColorOverride(item)
return @adapter.getBaseColorOverride(item)
end
def getShadowColorOverride(item)
return @adapter.getShadowColorOverride(item)
end
def isSelling?
return false
end
def getSpecialItemCaption(specialType)
return @adapter.getSpecialItemCaption(specialType)
end
def getSpecialItemBaseColor(specialType)
return @adapter.getSpecialItemBaseColor(specialType)
end
def getSpecialItemShadowColor(specialType)
return @adapter.getSpecialItemShadowColor(specialType)
end
def getAdapter()
return @adapter
end
end
#===============================================================================
#
#===============================================================================
class SellAdapter
def initialize(adapter)
@adapter = adapter
end
def getDisplayName(item)
@adapter.getDisplayName(item)
end
def getDisplayPrice(item)
if @adapter.showQuantity?(item)
return sprintf("x%d", @adapter.getQuantity(item))
else
return ""
end
end
def isSelling?
return true
end
def getBaseColorOverride(item)
return @adapter.getBaseColorOverride(item)
end
def getShadowColorOverride(item)
return @adapter.getShadowColorOverride(item)
end
end
#===============================================================================
# Pokémon Mart
#===============================================================================
class Window_PokemonMart < Window_DrawableCommand
def initialize(stock, adapter, x, y, width, height, viewport = nil)
@stock = stock
@adapter = adapter
super(x, y, width, height, viewport)
@selarrow = AnimatedBitmap.new("Graphics/UI/Mart/martSel")
@baseColor = Color.new(88, 88, 80)
@shadowColor = Color.new(168, 184, 184)
self.windowskin = nil
end
def itemCount
return @stock.length + 1
end
def item
return (self.index >= @stock.length) ? nil : @stock[self.index]
end
def drawItem(index, count, rect)
textpos = []
rect = drawCursor(index, rect)
ypos = rect.y
if index == count - 1
textpos.push([_INTL("CANCEL"), rect.x, ypos - 4, false, self.baseColor, self.shadowColor])
else
item = @stock[index]
if item.is_a?(Symbol) && @adapter.getAdapter().is_a?(OutfitsMartAdapter)
itemname = @adapter.getSpecialItemCaption(item)
baseColor = @adapter.getSpecialItemBaseColor(item) ? @adapter.getSpecialItemBaseColor(item) : baseColor
shadowColor = @adapter.getSpecialItemShadowColor(item) ? @adapter.getSpecialItemShadowColor(item) : shadowColor
textpos.push([itemname, rect.x, ypos - 4, false, baseColor, shadowColor])
else
itemname = @adapter.getDisplayName(item)
baseColorOverride = @adapter.getBaseColorOverride(item)
shadowColorOverride = @adapter.getShadowColorOverride(item)
baseColor = baseColorOverride ? baseColorOverride : self.baseColor
shadowColor = shadowColorOverride ? shadowColorOverride : self.shadowColor
qty = @adapter.getDisplayPrice(item)
sizeQty = self.contents.text_size(qty).width
xQty = rect.x + rect.width - sizeQty - 2 - 16
textpos.push([itemname, rect.x, ypos - 4, false, baseColor, shadowColor])
textpos.push([qty, xQty, ypos - 4, false, baseColor, shadowColor])
end
end
pbDrawTextPositions(self.contents, textpos)
end
end
#===============================================================================
#
#===============================================================================
class PokemonMart_Scene
def initialize(currency_name = "Money")
@currency_name = currency_name
end
def update
pbUpdateSpriteHash(@sprites)
@subscene.pbUpdate if @subscene
end
def pbRefresh
if @subscene
@subscene.pbRefresh
else
itemwindow = @sprites["itemwindow"]
@sprites["icon"].item = itemwindow.item
@sprites["itemtextwindow"].text =
(itemwindow.item) ? @adapter.getDescription(itemwindow.item) : _INTL("Quit shopping.")
itemwindow.refresh
end
@sprites["moneywindow"].text = _INTL("{2}:\r\n<r>{1}", @adapter.getMoneyString, @currency_name)
end
def scroll_map()
pbScrollMap(6, 5, 5)
end
def scroll_back_map()
pbScrollMap(4, 5, 5)
end
def pbStartBuyOrSellScene(buying, stock, adapter)
# Scroll right before showing screen
scroll_map()
@viewport = Viewport.new(0, 0, Graphics.width, Graphics.height)
@viewport.z = 99999
@stock = stock
@adapter = adapter
@sprites = {}
@sprites["background"] = IconSprite.new(0, 0, @viewport)
@sprites["background"].setBitmap("Graphics/Pictures/martScreen")
@sprites["icon"] = ItemIconSprite.new(36, Graphics.height - 50, nil, @viewport)
winAdapter = buying ? BuyAdapter.new(adapter) : SellAdapter.new(adapter)
@sprites["itemwindow"] = Window_PokemonMart.new(stock, winAdapter,
Graphics.width - 316 - 16, 12, 330 + 16, Graphics.height - 126)
@sprites["itemwindow"].viewport = @viewport
@sprites["itemwindow"].index = 0
@sprites["itemwindow"].refresh
@sprites["itemtextwindow"] = Window_UnformattedTextPokemon.newWithSize("",
64, Graphics.height - 96 - 16, Graphics.width - 64, 128, @viewport)
pbPrepareWindow(@sprites["itemtextwindow"])
@sprites["itemtextwindow"].baseColor = Color.new(248, 248, 248)
@sprites["itemtextwindow"].shadowColor = Color.new(0, 0, 0)
@sprites["itemtextwindow"].windowskin = nil
@sprites["helpwindow"] = Window_AdvancedTextPokemon.new("")
pbPrepareWindow(@sprites["helpwindow"])
@sprites["helpwindow"].visible = false
@sprites["helpwindow"].viewport = @viewport
pbBottomLeftLines(@sprites["helpwindow"], 1)
@sprites["moneywindow"] = Window_AdvancedTextPokemon.new("")
pbPrepareWindow(@sprites["moneywindow"])
@sprites["moneywindow"].setSkin("Graphics/Windowskins/goldskin")
@sprites["moneywindow"].visible = true
@sprites["moneywindow"].viewport = @viewport
@sprites["moneywindow"].x = 0
@sprites["moneywindow"].y = 0
@sprites["moneywindow"].width = 190
@sprites["moneywindow"].height = 96
@sprites["moneywindow"].baseColor = Color.new(88, 88, 80)
@sprites["moneywindow"].shadowColor = Color.new(168, 184, 184)
pbDeactivateWindows(@sprites)
@buying = buying
pbRefresh
Graphics.frame_reset
end
def pbStartBuyScene(stock, adapter)
pbStartBuyOrSellScene(true, stock, adapter)
end
def pbStartSellScene(bag, adapter)
if $PokemonBag
pbStartSellScene2(bag, adapter)
else
pbStartBuyOrSellScene(false, bag, adapter)
end
end
def pbStartSellScene2(bag, adapter)
@subscene = PokemonBag_Scene.new
@adapter = adapter
@viewport2 = Viewport.new(0, 0, Graphics.width, Graphics.height)
@viewport2.z = 99999
numFrames = Graphics.frame_rate * 4 / 10
alphaDiff = (255.0 / numFrames).ceil
for j in 0..numFrames
col = Color.new(0, 0, 0, j * alphaDiff)
@viewport2.color = col
Graphics.update
Input.update
end
@subscene.pbStartScene(bag)
@viewport = Viewport.new(0, 0, Graphics.width, Graphics.height)
@viewport.z = 99999
@sprites = {}
@sprites["helpwindow"] = Window_AdvancedTextPokemon.new("")
pbPrepareWindow(@sprites["helpwindow"])
@sprites["helpwindow"].visible = false
@sprites["helpwindow"].viewport = @viewport
pbBottomLeftLines(@sprites["helpwindow"], 1)
@sprites["moneywindow"] = Window_AdvancedTextPokemon.new("")
pbPrepareWindow(@sprites["moneywindow"])
@sprites["moneywindow"].setSkin("Graphics/Windowskins/goldskin")
@sprites["moneywindow"].visible = false
@sprites["moneywindow"].viewport = @viewport
@sprites["moneywindow"].x = 0
@sprites["moneywindow"].y = 0
@sprites["moneywindow"].width = 186
@sprites["moneywindow"].height = 96
@sprites["moneywindow"].baseColor = Color.new(88, 88, 80)
@sprites["moneywindow"].shadowColor = Color.new(168, 184, 184)
pbDeactivateWindows(@sprites)
@buying = false
pbRefresh
end
def pbEndBuyScene
pbDisposeSpriteHash(@sprites)
Kernel.pbClearText()
@viewport.dispose
# Scroll left after showing screen
scroll_back_map()
end
def pbEndSellScene
@subscene.pbEndScene if @subscene
pbDisposeSpriteHash(@sprites)
if @viewport2
numFrames = Graphics.frame_rate * 4 / 10
alphaDiff = (255.0 / numFrames).ceil
for j in 0..numFrames
col = Color.new(0, 0, 0, (numFrames - j) * alphaDiff)
@viewport2.color = col
Graphics.update
Input.update
end
@viewport2.dispose
end
@viewport.dispose
pbScrollMap(4, 5, 5) if !@subscene
end
def pbPrepareWindow(window)
window.visible = true
window.letterbyletter = false
end
def pbShowMoney
pbRefresh
@sprites["moneywindow"].visible = true
end
def pbHideMoney
pbRefresh
@sprites["moneywindow"].visible = false
end
def pbDisplay(msg, brief = false)
cw = @sprites["helpwindow"]
cw.letterbyletter = true
cw.text = msg
pbBottomLeftLines(cw, 2)
cw.visible = true
i = 0
pbPlayDecisionSE
loop do
Graphics.update
Input.update
self.update
if !cw.busy?
return if brief
pbRefresh if i == 0
end
if Input.trigger?(Input::USE) && cw.busy?
cw.resume
end
return if i >= Graphics.frame_rate * 3 / 2
i += 1 if !cw.busy?
end
end
def pbDisplayPaused(msg)
cw = @sprites["helpwindow"]
cw.letterbyletter = true
cw.text = msg
pbBottomLeftLines(cw, 2)
cw.visible = true
yielded = false
pbPlayDecisionSE
loop do
Graphics.update
Input.update
wasbusy = cw.busy?
self.update
if !cw.busy? && !yielded
yield if block_given? # For playing SE as soon as the message is all shown
yielded = true
end
pbRefresh if !cw.busy? && wasbusy
if Input.trigger?(Input::USE) && cw.resume && !cw.busy?
@sprites["helpwindow"].visible = false
return
end
end
end
def pbConfirm(msg)
dw = @sprites["helpwindow"]
dw.letterbyletter = true
dw.text = msg
dw.visible = true
pbBottomLeftLines(dw, 2)
commands = [_INTL("Yes"), _INTL("No")]
cw = Window_CommandPokemon.new(commands)
cw.viewport = @viewport
pbBottomRight(cw)
cw.y -= dw.height
cw.index = 0
pbPlayDecisionSE
loop do
cw.visible = !dw.busy?
Graphics.update
Input.update
cw.update
self.update
if Input.trigger?(Input::BACK) && dw.resume && !dw.busy?
cw.dispose
@sprites["helpwindow"].visible = false
return false
end
if Input.trigger?(Input::USE) && dw.resume && !dw.busy?
cw.dispose
@sprites["helpwindow"].visible = false
return (cw.index == 0)
end
end
end
def pbChooseNumber(helptext, item, maximum)
curnumber = 1
ret = 0
helpwindow = @sprites["helpwindow"]
itemprice = @adapter.getPrice(item, !@buying)
itemprice /= 2 if !@buying
pbDisplay(helptext, true)
using(numwindow = Window_AdvancedTextPokemon.new("")) { # Showing number of items
qty = @adapter.getQuantity(item)
using(inbagwindow = Window_AdvancedTextPokemon.new("")) { # Showing quantity in bag
pbPrepareWindow(numwindow)
pbPrepareWindow(inbagwindow)
numwindow.viewport = @viewport
numwindow.width = 224
numwindow.height = 64
numwindow.baseColor = Color.new(88, 88, 80)
numwindow.shadowColor = Color.new(168, 184, 184)
inbagwindow.visible = @buying
inbagwindow.viewport = @viewport
inbagwindow.width = 190
inbagwindow.height = 64
inbagwindow.baseColor = Color.new(88, 88, 80)
inbagwindow.shadowColor = Color.new(168, 184, 184)
inbagwindow.text = _INTL("In Bag:<r>{1} ", qty)
numwindow.text = _INTL("x{1}<r>$ {2}", curnumber, (curnumber * itemprice).to_s_formatted)
pbBottomRight(numwindow)
numwindow.y -= helpwindow.height
pbBottomLeft(inbagwindow)
inbagwindow.y -= helpwindow.height
loop do
Graphics.update
Input.update
numwindow.update
inbagwindow.update
self.update
if Input.repeat?(Input::LEFT)
pbPlayCursorSE
curnumber -= 10
curnumber = 1 if curnumber < 1
numwindow.text = _INTL("x{1}<r>$ {2}", curnumber, (curnumber * itemprice).to_s_formatted)
elsif Input.repeat?(Input::RIGHT)
pbPlayCursorSE
curnumber += 10
curnumber = maximum if curnumber > maximum
numwindow.text = _INTL("x{1}<r>$ {2}", curnumber, (curnumber * itemprice).to_s_formatted)
elsif Input.repeat?(Input::UP)
pbPlayCursorSE
curnumber += 1
curnumber = 1 if curnumber > maximum
numwindow.text = _INTL("x{1}<r>$ {2}", curnumber, (curnumber * itemprice).to_s_formatted)
elsif Input.repeat?(Input::DOWN)
pbPlayCursorSE
curnumber -= 1
curnumber = maximum if curnumber < 1
numwindow.text = _INTL("x{1}<r>$ {2}", curnumber, (curnumber * itemprice).to_s_formatted)
elsif Input.trigger?(Input::USE)
pbPlayDecisionSE
ret = curnumber
break
elsif Input.trigger?(Input::BACK)
pbPlayCancelSE
ret = 0
break
end
end
}
}
helpwindow.visible = false
return ret
end
def pbChooseBuyItem
itemwindow = @sprites["itemwindow"]
@sprites["helpwindow"].visible = false
pbActivateWindow(@sprites, "itemwindow") {
pbRefresh
loop do
Graphics.update
Input.update
olditem = itemwindow.item
self.update
if itemwindow.item != olditem
@sprites["icon"].item = itemwindow.item
@sprites["itemtextwindow"].text =
(itemwindow.item) ? @adapter.getDescription(itemwindow.item) : _INTL("Quit shopping.")
end
if Input.trigger?(Input::BACK)
pbPlayCloseMenuSE
return nil
elsif Input.trigger?(Input::USE)
if itemwindow.index < @stock.length
pbRefresh
return @stock[itemwindow.index]
else
return nil
end
end
end
}
end
def pbChooseSellItem
if @subscene
return @subscene.pbChooseItem
else
return pbChooseBuyItem
end
end
end
#===============================================================================
#
#===============================================================================
class PokemonMartScreen
def initialize(scene, stock, adapter = PokemonMartAdapter.new)
@scene = scene
@stock = stock
@adapter = adapter
end
def pbConfirm(msg)
return @scene.pbConfirm(msg)
end
def pbDisplay(msg)
return @scene.pbDisplay(msg)
end
def pbDisplayPaused(msg, &block)
return @scene.pbDisplayPaused(msg, &block)
end
def pbBuyScreen
@scene.pbStartBuyScene(@stock, @adapter)
item = nil
loop do
pbWait(4)
item = @scene.pbChooseBuyItem
break if !item
quantity = 0
itemname = @adapter.getDisplayName(item)
price = @adapter.getPrice(item)
if @adapter.getMoney < price
pbDisplayPaused(_INTL("You don't have enough money."))
next
end
if GameData::Item.get(item).is_important?
if !pbConfirm(_INTL("Certainly. You want {1}. That will be ${2}. OK?",
itemname, price.to_s_formatted))
next
end
quantity = 1
else
maxafford = (price <= 0) ? Settings::BAG_MAX_PER_SLOT : @adapter.getMoney / price
maxafford = Settings::BAG_MAX_PER_SLOT if maxafford > Settings::BAG_MAX_PER_SLOT
quantity = @scene.pbChooseNumber(
_INTL("{1}? Certainly. How many would you like?", itemname), item, maxafford)
next if quantity == 0
price *= quantity
if !pbConfirm(_INTL("{1}, and you want {2}. That will be ${3}. OK?",
itemname, quantity, price.to_s_formatted))
next
end
end
if @adapter.getMoney < price
pbDisplayPaused(_INTL("You don't have enough money."))
next
end
added = 0
quantity.times do
break if !@adapter.addItem(item)
added += 1
end
if added != quantity
added.times do
if !@adapter.removeItem(item)
raise _INTL("Failed to delete stored items")
end
end
pbDisplayPaused(_INTL("You have no more room in the Bag."))
else
@adapter.setMoney(@adapter.getMoney - price)
for i in 0...@stock.length
if GameData::Item.get(@stock[i]).is_important? && $PokemonBag.pbHasItem?(@stock[i])
@stock[i] = nil
end
end
@stock.compact!
pbDisplayPaused(_INTL("Here you are! Thank you!")) { pbSEPlay("Mart buy item") }
if $PokemonBag
if quantity >= 10 && GameData::Item.get(item).is_poke_ball? && GameData::Item.exists?(:PREMIERBALL)
if @adapter.addItem(GameData::Item.get(:PREMIERBALL))
pbDisplayPaused(_INTL("I'll throw in a Premier Ball, too."))
end
end
end
end
end
@scene.pbEndBuyScene
end
def pbSellScreen
item = @scene.pbStartSellScene(@adapter.getInventory, @adapter)
loop do
item = @scene.pbChooseSellItem
break if !item
itemname = @adapter.getDisplayName(item)
price = @adapter.getPrice(item, true)
if !@adapter.canSell?(item)
pbDisplayPaused(_INTL("{1}? Oh, no. I can't buy that.", itemname))
next
end
qty = @adapter.getQuantity(item)
next if qty == 0
@scene.pbShowMoney
if qty > 1
qty = @scene.pbChooseNumber(
_INTL("{1}? How many would you like to sell?", itemname), item, qty)
end
if qty == 0
@scene.pbHideMoney
next
end
price /= 2
price *= qty
if pbConfirm(_INTL("I can pay ${1}. Would that be OK?", price.to_s_formatted))
@adapter.setMoney(@adapter.getMoney + price)
qty.times do
@adapter.removeItem(item)
end
pbDisplayPaused(_INTL("Turned over the {1} and received ${2}.", itemname, price.to_s_formatted)) { pbSEPlay("Mart buy item") }
@scene.pbRefresh
end
@scene.pbHideMoney
end
@scene.pbEndSellScene
end
end
def replaceShopStockWithRandomized(stock)
if $PokemonGlobal.randomItemsHash != nil
newStock = []
for item in stock
newItem = $PokemonGlobal.randomItemsHash[item]
if newItem != nil && GameData::Item.get(newItem).price > 0 && !Settings::EXCLUDE_FROM_RANDOM_SHOPS.include?(newItem)
newStock << newItem
else
newStock << item
end
end
return newStock
end
return stock
end
#===============================================================================
#
#===============================================================================
def pbPokemonMart(stock, speech = nil, cantsell = false)
if $game_switches[SWITCH_RANDOM_ITEMS_GENERAL] && $game_switches[SWITCH_RANDOM_SHOP_ITEMS]
stock = replaceShopStockWithRandomized(stock)
end
for i in 0...stock.length
stock[i] = GameData::Item.get(stock[i]).id
stock[i] = nil if GameData::Item.get(stock[i]).is_important? && $PokemonBag.pbHasItem?(stock[i])
end
stock.compact!
commands = []
cmdBuy = -1
cmdSell = -1
cmdQuit = -1
commands[cmdBuy = commands.length] = _INTL("Buy")
commands[cmdSell = commands.length] = _INTL("Sell") if !cantsell
commands[cmdQuit = commands.length] = _INTL("Quit")
cmd = pbMessage(
speech ? speech : _INTL("Welcome! How may I serve you?"),
commands, cmdQuit + 1)
loop do
if cmdBuy >= 0 && cmd == cmdBuy
scene = PokemonMart_Scene.new
screen = PokemonMartScreen.new(scene, stock)
screen.pbBuyScreen
elsif cmdSell >= 0 && cmd == cmdSell
scene = PokemonMart_Scene.new
screen = PokemonMartScreen.new(scene, stock)
screen.pbSellScreen
else
pbMessage(_INTL("Please come again!"))
break
end
cmd = pbMessage(_INTL("Is there anything else I can help you with?"),
commands, cmdQuit + 1)
end
$game_temp.clear_mart_prices
end

View File

@@ -0,0 +1,63 @@
class PokemonBag
def pbQuantity(item)
return quantity(item)
end
def pbHasItem?(item, qty = 1)
return has?(item, qty)
end
def pbCanStore?(item, qty = 1)
return can_add?(item, qty = 1)
end
def pbStoreItem(item, qty = 1)
return add(item, qty = 1)
end
def pbStoreAllOrNone(item, qty = 1)
add_all(item, qty = 1)
end
def pbChangeItem(old_item, new_item)
replace_item(old_item, new_item)
end
def pbDeleteItem(item, qty = 1)
remove(item, qty = 1)
end
def pbIsRegistered?(item)
registered?(item)
end
def pbRegisterItem(item)
register(item)
end
def pbUnregisterItem(item)
unregister(item)
end
end
#Shortcut methods
def pbQuantity(*args)
return $bag.pbQuantity(*args)
end
def pbHasItem?(*args)
return $bag.pbHasItem?(*args)
end
def pbCanStore?(*args)
return $bag.pbCanStore?(*args)
end
def pbStoreItem(*args)
return $bag.pbStoreItem(*args)
end
def pbStoreAllOrNone(*args)
return $bag.pbStoreAllOrNone(*args)
end

View File

@@ -0,0 +1,4 @@
module MessageConfig
BLUE_TEXT_MAIN_COLOR = Color.new(35, 130, 200)
BLUE_TEXT_SHADOW_COLOR = Color.new(20, 75, 115)
end

View File

@@ -0,0 +1,50 @@
module GameData
class Species
def id_number
return (GameData::Species.keys.index(@id) || 0) + 1
end
def type1
return @types[0]
end
def type2
return @types[-1]
end
def is_fusion
return id_number > Settings::NB_POKEMON
end
def is_triple_fusion
return id_number >= Settings::ZAPMOLCUNO_NB
end
def get_body_species
return @species
end
def get_head_species
return @species
end
def hasType?(type)
type = GameData::Type.get(type).id
return self.types.include?(type)
end
def self.get_species_form(species, form)
return nil if !species || !form
return GameData::Species.get(species)
validate species => [Symbol, self, String]
validate form => Integer
species = species.species if species.is_a?(self)
species = species.to_sym if species.is_a?(String)
trial = sprintf("%s_%d", species, form).to_sym
species_form = (DATA[trial].nil?) ? species : trial
return (DATA.has_key?(species_form)) ? DATA[species_form] : nil
end
end
end

View File

@@ -0,0 +1,29 @@
# frozen_string_literal: true
class Scene_Map
def cacheNeedsClearing
return RPG::Cache.size >= 100
end
def reset_switches_for_map_transfer
$game_switches[SWITCH_ILEX_FOREST_SPOOKED_POKEMON] = false
end
def clear_quest_icons()
for sprite in $scene.spriteset.character_sprites
if sprite.is_a?(Sprite_Character) && sprite.questIcon
sprite.removeQuestIcon
end
end
end
alias pokemonEssentials_SceneMap_transfer_player transfer_player
def transfer_playerr(cancel_swimming = true)
pokemonEssentials_SceneMap_transfer_player(cancel_swimming)
reset_switches_for_map_transfer()
clear_quest_icons()
end
end

View File

@@ -0,0 +1,12 @@
def pbChoosePokemon(helptext,index_game_var=1, name_game_var=2, able_proc = nil, _allow_ineligible = false)
set_help_text(_INTL(helptext))
chosen = -1
pbFadeOutIn do
screen = UI::Party.new($player.party, mode: :choose_pokemon)
screen.set_able_annotation_proc(able_proc) if able_proc
chosen = screen.choose_pokemon
end
pbSet(index_game_var, chosen)
pbSet(name_game_var, (chosen >= 0) ? $player.party[chosen].name : "")
return chosen
end

View File

@@ -0,0 +1,31 @@
#############
# SETTINGS #
#############
# This is for settings that are used in scripts since it's a chore to change them everywhere to include the module name
NUM_BADGES = Settings::NB_BADGES
EGGINITIALLEVEL = Settings::EGG_LEVEL
#this is fucking stupid but apparently necessary
FALSE = false
TRUE = true
DIRECTION_LEFT = 4
DIRECTION_RIGHT = 6
DIRECTION_DOWN = 2
DIRECTION_UP = 8
VAR_SPEED_UP_TOGGLE_SPEED=23
MAP_TEMPLATE_EVENTS = 175
TEMPLATE_EVENT_SILHOUETTE = 7
SWITCH_TRIPLE_BOSS_BATTLE = 824
SWITCH_SILVERBOSS_BATTLE = 675
GENDER_FEMALE=0
GENDER_MALE=1
MELOETTA_BAND_NAME = "Miss Melody and the Mystic Musicians"
SUCKY_BAND_NAME = "MooMoo Milk"

View File

@@ -0,0 +1,6 @@
##############
# ANIMATIONS
################
DUST_ANIMATION_ID=2
VIRUS_ANIMATION_ID=10# frozen_string_literal: true

View File

@@ -0,0 +1,3 @@
UI_FOLDER = "Graphics/UI/"
# frozen_string_literal: true

View File

@@ -0,0 +1,93 @@
# frozen_string_literal: true
KANTO_OUTDOOR_MAPS = [
78, # Route 1
185, # Secret Garden
86, # Route 2
90, # Route 2 (north)
655, # Hidden Forest
40, # Viridian River
490, # Route 3
106, # Route 4
12, # Route 5
16, # Route 6
413, # Route 7
409, # Route 8
351, # Route 9 (east)
495, # Route 9 (west)
154, # Route 10
155, # Route 11
159, # Route 12
440, # Route 14
444, # Route 15
712, # Creepy house
438, # Route 16
146, # Route 17
517, # Route 18
437, # Route 13
57, # Route 19
227, # Route 19 (underwater)
56, # Route 19 (surf race)
58, # Route 20
480, # Route 20 underwater 1
228, # Route 20 underwater 2
171, # Route 22
8, # Route 24
9, # Route 25
143, # Route 23
145, # Route 26
147, # Route 27
58, # Route 21
# CITIES
42, # Pallet Town
79, # Viridian City
1, # Cerulean City
387, # Cerulean City (race)
19, # Vermillion City
36, # S.S. Anne deck
95, # Celadon city
436, # Celadon city dept store (roof)
472, # Fuchsia city
50, # Lavender town
108, # Saffron city
98, # Cinnabar island
167, # Crimson city
303, # indigo plateau
380, # Pewter city
827, # Mt. Moon summit
#
# DUNGEONS
#
102, # Mt. Moon
103, # Mt. Moon
105, # Mt. Moon
496, # Mt Moon
104, # Mt. Moon
494, # Mt. Moon Square
140, # Diglett cave
398, # Diglett cave
399, # Diglett cave
349, # Rock tunnel
350, # Rock tunnel
512, # Rock tunnel (outdoor)
445, # Safari Zone 1
484, # Safari Zone 2
485, # Safari Zone 3
486, # Safari Zone 4
487, # Safari Zone 5
491, # Viridian Forest
529, # Mt. Silver entrance
777, # Mt. Silver outdoor 1
781, # Mt. Silver outdoor 2
782, # Mt. Silver
783, # Mt. Silver summit
400, # Pokemon Tower
401, # Pokemon Tower
402, # Pokemon Tower
403, # Pokemon Tower
467, # Pokemon Tower
468, # Pokemon Tower
469, # Pokemon Tower
]

View File

@@ -0,0 +1,131 @@
# frozen_string_literal: true
#############
# VARIABLES #
#############
VAR_CURRENT_MART=291
VAR_CURRENT_CITY_NUMERICAL_ID=14 #for wondertrade/pokemarts
VAR_SINGLE_POKEMON_MODE=251
SINGLE_POKEMON_MODE_VAR=251 #c'est appellé comme ca en qqpart dans un event pis ca me tente pas de chercher ou
VAR_WILD_FUSION_RATE=210
VAR_ODDKEYSTONE_NB=252
VAR_DEFAULT_BATTLE_TYPE = 242
VAR_BATTLE_FACTORY_TOKENS = 243
VAR_NB_GYM_REMATCHES = 162
VAR_CUSTOM_SPRITES_ENABLED= 196
VAR_COMMAND_WINDOW_INDEX=249
VAR_STANDARD_WONDERTRADE_LEFT=248
VAR_PREMIUM_WONDERTRADE_LEFT=111
VAR_PREMIUM_WONDERTRADE_LEFT=111
VAR_RIVAL_STARTER=250
VAR_FUSION_ICON_STYLE=220
VAR_SHINY_HUE_OFFSET=275
VAR_CURRENT_HIDDEN_MAP = 226
VAR_FUSE_COUNTER = 126
VAR_STAT_RARE_CANDY=265
VAR_STAT_LEADER_REMATCH=162
VAR_STAT_NB_FUSIONS=126
VAR_STAT_NB_ELITE_FOUR=174
VAR_STAT_NB_WONDERTRADES=164
VAR_STAT_CLOWN_TIP_TOTAL=100
VAR_STAT_NB_SANDCASTLES=163
VAR_STAT_GAMBLER_WINS=43
VAR_STAT_GAMBLER_LOSSES=44
VAR_STAT_HOTELS_SPENT=225
VAR_NB_EGGS_HATCHED=298
VAR_STAT_QUESTS_ACCEPTED=96
VAR_STAT_QUESTS_COMPLETED=98
VAR_NB_ROCKET_MISSIONS = 286
VAR_BOUTIQUE_OUTFIT=290
VAR_FISHING_CONTEST_RECORD=294
VAR_FISHING_CONTEST_NERF=333
VAR_STAT_NB_SECRETS=193
VAR_STAT_FUSION_QUIZ_HIGHEST_SCORE=267
VAR_STAT_FUSION_QUIZ_NB_TIMES=268
VAR_STAT_FUSION_QUIZ_TOTAL_PTS=269
VAR_KARMA=222
VAR_NB_QUEST_ACTIVE=97
VAR_NB_QUEST_COMPLETED=98
VAR_LUNAR_FEATHERS=282
VAR_FOSSIL=271
VAR_SSANNE_MENU=313
VAR_TEMP_SSANNE_ORDER=314
VAR_TEMP_SSANNE_PLATE=325
VAR_SSANNE_DISHES_HELD_ARRAY=316
VAR_BATTLE_TOWER_MIN_BST = 257
VAR_BATTLE_TOWER_MAX_BST = 258
VAR_GALLERY_FEATURED_ARTIST = 259
VAR_GALLERY_FEATURED_SPRITES = 260
VAR_GALLERY_ALL_ARTIST_SPRITES = 261
VAR_GALLERY_SELECTED_ARTIST = 263
VAR_NEXT_ARTIST_FORMATTED = 264
VAR_RADIO_POINTS=266
VAR_TRAINER_GENDER=52
VAR_TRAINER_AGE=99
VAR_ROCKET_NAME=25
VAR_NB_CRIMES_REPORTED=300
VAR_EXOTIC_POKEMON_ID=327
VAR_TYPE_EXPERTS_BEATEN=332
TOTAL_NB_TYPE_EXPERTS=331
#Randomizer
VAR_RANDOMIZER_WILD_POKE_BST=197
VAR_RANDOMIZER_TRAINER_BST=195
VAR_GYM_TYPES_ARRAY=151
VAR_CURRENT_GYM_TYPE=152
#constellations
VAR_CONSTELLATION_IVYSAUR=301
VAR_CONSTELLATION_WARTORTLE=302
VAR_CONSTELLATION_ARCANINE=303
VAR_CONSTELLATION_MACHOKE=304
VAR_CONSTELLATION_RAPIDASH=305
VAR_CONSTELLATION_GYARADOS=306
VAR_CONSTELLATION_ARTICUNO=307
VAR_CONSTELLATION_MEW=308
VAR_CONSTELLATION_POLITOED=309
VAR_CONSTELLATION_URSARING=310
VAR_CONSTELLATION_LUGIA=311
VAR_CONSTELLATION_HOOH=312
VAR_CONSTELLATION_CELEBI=313
VAR_CONSTELLATION_SLAKING=314
VAR_CONSTELLATION_JIRACHI=315
VAR_CONSTELLATION_TYRANTRUM=316
VAR_CONSTELLATION_SHARPEDO=317
VAR_CONSTELLATION_ARCEUS=318
VAR_LATEST_CONSTELLATION=319
VAR_TRAINER_CARD_BACKGROUND_PRICE=329
VAR_GALLERY_TEAM_FLAGS=330
VAR_REGI_PUZZLE_SWITCH_PRESSED = 1122
##############
# COMMON EVENTS
################
COMMON_EVENT_REGI_TABLET = 84
COMMON_EVENT_SILHOUETTE = 87
COMMON_EVENT_HOTEL = 12
COMMON_EVENT_SINGLESPECIES_MODE = 73
COMMON_EVENT_OUTFIT = 80
COMMON_EVENT_FIX_GAME = 16
COMMON_EVENT_IDLE_HAT = 100
COMMON_EVENT_PINKAN_WHISTLE = 106
COMMON_EVENT_PINKAN_BACK_TO_BEGIN = 103

View File

@@ -0,0 +1,172 @@
# frozen_string_literal: true
#############
# SWITCHES #
#############
#Game mode switches
SWITCH_NEW_GAME_PLUS = 972
SWITCH_BEAT_MT_SILVER = 918
BEAT_MT_SILVER = 918 #don't remove this - used in some events
SWITCH_REVERSED_MODE = 47
SWITCH_GAME_DIFFICULTY_EASY = 665
SWITCH_GAME_DIFFICULTY_HARD = 666
SWITCH_MODERN_MODE=974
SWITCH_EXPERT_MODE=772
SWITCH_V5_1=825
SWITCH_NO_LEVELS_MODE=774
SWITCH_DOUBLE_ABILITIES=773
SWITCH_SINGLE_SPECIES_MODE=790
#Game progression switches
SWITCH_DURING_INTRO = 917
SWITCH_CHOOSING_STARTER=3
SWITCH_GOT_BADGE_1 = 4
SWITCH_GOT_BADGE_2 = 5
SWITCH_GOT_BADGE_3 = 6
SWITCH_GOT_BADGE_4 = 7
SWITCH_GOT_BADGE_5 = 8
SWITCH_GOT_BADGE_6 = 9
SWITCH_GOT_BADGE_7 = 10
SWITCH_GOT_BADGE_8 = 11
SWITCH_BEAT_THE_LEAGUE = 12
SWITCH_GOT_BADGE_9 = 38
SWITCH_GOT_BADGE_10 = 39
SWITCH_GOT_BADGE_11 = 40
SWITCH_GOT_BADGE_12 = 41
SWITCH_GOT_BADGE_13 = 43
SWITCH_GOT_BADGE_14 = 44
SWITCH_GOT_BADGE_15 = 45
SWITCH_GOT_BADGE_16 = 50
SWITCH_KANTO_DARKNESS = 701
SWITCH_KANTO_DARKNESS_STAGE_1 = 702
SWITCH_KANTO_DARKNESS_STAGE_2 = 703
SWITCH_KANTO_DARKNESS_STAGE_3 = 704
SWITCH_KANTO_DARKNESS_STAGE_4 = 705
SWITCH_ORICORIO_QUEST_PINK = 672
SWITCH_ORICORIO_QUEST_RED = 673
SWITCH_ORICORIO_QUEST_BLUE = 674
SWITCH_ORICORIO_QUEST_IN_PROGRESS = 680
SWITCH_PICKED_HELIC_FOSSIL= 65
SWITCH_PICKED_DOME_FOSSIL= 66
SWITCH_PICKED_LILEEP_FOSSIL= 589
SWITCH_PICKED_ANORITH_FOSSIL= 90
SWITCH_PICKED_ARMOR_FOSSIL= 616
SWITCH_PICKED_SKULL_FOSSIL= 617
SWITCH_NIGHTMARE_EFFECT= 805
SWITCH_JOHTO_STARTERS=884
SWITCH_HOENN_STARTERS=885
SWITCH_SINNOH_STARTERS=886
SWITCH_KALOS_STARTERS=888
SWITCH_CUSTOM_STARTERS=883
SWITCH_JOINED_TEAM_ROCKET=1037
SWITCH_PINKAN_SIDE_ROCKET=1099
SWITCH_PINKAN_SIDE_POLICE=1100
SWITCH_LEAVING_PINKAN_ISLAND=1113
SWITCH_BLOCK_PINKAN_WHISTLE=1111
SWITCH_PINKAN_FINISHED=1119
VAR_ORICORIO_FLOWERS = 276
#Randomizer Switches
SWITCH_RANDOM_WILD_TO_FUSION=953
SWITCH_RANDOMIZED_AT_LEAST_ONCE = 855
ENABLED_DEBUG_MODE_AT_LEAST_ONCE = 842
SWITCH_RANDOM_WILD = 778
SWITCH_RANDOM_WILD_AREA = 777
SWITCH_RANDOM_TRAINERS = 987
SWITCH_RANDOM_STARTERS = 954
SWITCH_RANDOM_STARTER_FIRST_STAGE = 771
SWITCH_RANDOM_ITEMS_GENERAL=759
SWITCH_RANDOM_ITEMS=751
SWITCH_RANDOM_FOUND_ITEMS=755
SWITCH_RANDOM_ITEMS_DYNAMIC = 958
SWITCH_RANDOM_ITEMS_MAPPED = 752
SWITCH_RANDOM_TMS = 758
SWITCH_RANDOM_GIVEN_ITEMS = 756
SWITCH_RANDOM_GIVEN_TMS = 757
SWITCH_RANDOM_SHOP_ITEMS = 754
SWITCH_RANDOM_FOUND_TMS = 959
SWITCH_WILD_RANDOM_GLOBAL=956
SWITCH_RANDOM_STATIC_ENCOUNTERS=955
SWITCH_RANDOM_WILD_ONLY_CUSTOMS=664
SWITCH_RANDOM_GYM_PERSIST_TEAMS=663
SWITCH_GYM_RANDOM_EACH_BATTLE = 668
SWITCH_RANDOM_GYM_CUSTOMS=662
SWITCH_RANDOMIZE_GYMS_SEPARATELY = 667
SWITCH_RANDOMIZED_GYM_TYPES=921
SWITCH_RANDOM_GIFT_POKEMON = 780
SWITCH_RANDOM_HELD_ITEMS = 843
SWITCH_DEFINED_RIVAL_STARTER=840
SWITCH_RANDOMIZED_WILD_POKEMON_TO_FUSIONS=829
SWITCH_RANDOM_WILD_LEGENDARIES=1031
SWITCH_RANDOM_TRAINER_LEGENDARIES=1032
SWITCH_RANDOM_GYM_LEGENDARIES=1033
SWITCH_DONT_RANDOMIZE=890
#Other switches
SWITCH_RACE_BIKE = 984
SWITCH_IS_REMATCH=200
SWITCH_SINGLE_POKEMON_MODE=790
SWITCH_SINGLE_POKEMON_MODE_HEAD=791
SWITCH_SINGLE_POKEMON_MODE_BODY=792
SWITCH_SINGLE_POKEMON_MODE_RANDOM=793
SWITCH_FISHING_AUTOHOOK = 916
SWITCH_FUSED_WILD_POKEMON=35
SWITCH_FORCE_FUSE_NEXT_POKEMON=37
SWITCH_FORCE_ALL_WILD_FUSIONS=828
SWITCH_USED_AN_INCENSE=798
SWITCH_FIRST_RIVAL_BATTLE=46
SWITCH_BATTLE_FACTORY_INCLUDE_ALL = 775
SWITCH_SUPER_SLOW_SPEED=649
SWITCH_LOUNGE_BATTLE_LEVEL = 240
SWITCH_CANNOT_CATCH_POKEMON = 75
SWITCH_UNLOCKED_POKEMON_HATS = 770
SWITCH_ILEX_FOREST_SPOOKED_POKEMON = 1021
SWITCH_LOCK_PLAYER_MOVEMENT = 815
SWITCH_TEAMED_WITH_ERIKA_SEWERS=141
SWITCH_BAND_DRUMMER = 1004
SWITCH_BAND_ACOUSTIC_GUITAR = 1005
SWITCH_BAND_ELECTRIC_GUITAR = 1006
SWITCH_BAND_HARP = 1007
SWITCH_BAND_FLUTE = 1008
SWITCH_SELECTING_CLOTHES = 804
SWITCH_KANTO_HAIR_COLLECTION = 1059
SWITCH_JOHTO_HAIR_COLLECTION = 1060
SWITCH_HOENN_HAIR_COLLECTION = 1061
SWITCH_SINNOH_HAIR_COLLECTION = 1062
SWITCH_UNOVA_HAIR_COLLECTION = 1063
SWITCH_KALOS_HAIR_COLLECTION = 1064
SWITCH_ALOLA_HAIR_COLLECTION = 1065
SWITCH_GALAR_HAIR_COLLECTION = 1066
SWITCH_PALDEA_HAIR_COLLECTION = 1067
SWITCH_GEN10_HAIR_COLLECTION = 1068
SWITCH_SS_ANNE_DEPARTED = 88
SWITCH_SNORLAX_GONE_ROUTE_12 = 110
SWITCH_TELEPORT_NPC = 122
SWITCH_GOT_DIVE = 317
SWITCH_GOT_ROCK_CLIMB = 661
SWITCH_GOT_WATERFALL = 388
SWITCH_UPDATED_TO_SPRITESHEETS_SPRITES=1117
#OUTFITS
#
WEARING_ROCKET_OUTFIT = 1038

View File

@@ -0,0 +1,225 @@
class DoublePreviewScreen
SELECT_ARROW_X_LEFT= 100
SELECT_ARROW_X_RIGHT= 350
SELECT_ARROW_X_CANCEL= 230
SELECT_ARROW_Y_SELECT= 0
SELECT_ARROW_Y_CANCEL= 210
ARROW_GRAPHICS_PATH = "Graphics/Pictures/Fusion/selHand"
CANCEL_BUTTON_PATH = "Graphics/Pictures/Fusion/previewScreen_Cancel"
BACKGROUND_PATH = "Graphics/Pictures/Fusion/shadeFull_"
CANCEL_BUTTON_X= 140
CANCEL_BUTTON_Y= 260
def initialize(species_left, species_right)
@species_left = species_left
@species_right = species_right
@typewindows = []
@picture1 = nil
@picture2 = nil
@draw_types = nil
@draw_level = nil
@draw_sprite_info = nil
@selected = 0
@last_post=0
@sprites = {}
initializeBackground
initializeSelectArrow
initializeCancelButton
end
def getBackgroundPicture
return BACKGROUND_PATH
end
def getSelection
selected = startSelection
@sprites["cancel"].visible=false
#@sprites["arrow"].visible=false
#todo: il y a un fuck en quelque part.... en attendant ca marche inversé ici
return @species_left if selected == 0
return @species_right if selected == 1
return -1
end
def startSelection
loop do
Graphics.update
Input.update
updateSelection
if Input.trigger?(Input::USE)
return @selected
end
if Input.trigger?(Input::BACK)
return -1
end
end
end
def updateSelection
currentSelected = @selected
updateSelectionIndex
if @selected != currentSelected
updateSelectionGraphics
end
end
def updateSelectionIndex
if Input.trigger?(Input::LEFT)
@selected = 0
elsif Input.trigger?(Input::RIGHT)
@selected = 1
end
if @selected == -1
if Input.trigger?(Input::UP)
@selected = @last_post
end
else
if Input.trigger?(Input::DOWN)
@last_post = @selected
@selected = -1
end
end
end
def updateSelectionGraphics
if @selected == 0
@sprites["arrow"].x = SELECT_ARROW_X_LEFT
@sprites["arrow"].y = SELECT_ARROW_Y_SELECT
elsif @selected == 1
@sprites["arrow"].x = SELECT_ARROW_X_RIGHT
@sprites["arrow"].y = SELECT_ARROW_Y_SELECT
else
@sprites["arrow"].x = SELECT_ARROW_X_CANCEL
@sprites["arrow"].y = SELECT_ARROW_Y_CANCEL
end
pbUpdateSpriteHash(@sprites)
end
def draw_window(dexNumber, level, x, y)
body_pokemon = getBodyID(dexNumber)
head_pokemon = getHeadID(dexNumber, body_pokemon)
# picturePath = getPicturePath(head_pokemon, body_pokemon)
# bitmap = AnimatedBitmap.new(picturePath)
spriteLoader = BattleSpriteLoader.new
bitmap = spriteLoader.load_fusion_sprite(head_pokemon,body_pokemon)
bitmap.scale_bitmap(Settings::FRONTSPRITE_SCALE)
pif_sprite = spriteLoader.obtain_fusion_pif_sprite(head_pokemon,body_pokemon)
#hasCustom = picturePath.include?("CustomBattlers")
#hasCustom = customSpriteExistsBase(body_pokemon,head_pokemon)
hasCustom = customSpriteExists(body_pokemon,head_pokemon)
previewwindow = PictureWindow.new(bitmap)
previewwindow.x = x
previewwindow.y = y
previewwindow.z = 100000
drawFusionInformation(dexNumber, level, x)
if !$Trainer.seen?(dexNumber)
if pif_sprite.local_path()
previewwindow.picture.pbSetColor(170, 200, 250, 200) #blue
elsif hasCustom
previewwindow.picture.pbSetColor(150, 255, 150, 200) #green
else
previewwindow.picture.pbSetColor(255, 255, 255, 200) #white
end
end
return previewwindow
end
def drawFusionInformation(fusedDexNum, level, x = 0)
viewport = Viewport.new(0, 0, Graphics.width, Graphics.height)
@typewindows << drawPokemonType(fusedDexNum, viewport, x + 55, 220) if @draw_types
drawFusionPreviewText(viewport, "Lv. " + level.to_s, x + 80, 40,) if @draw_level
drawSpriteInfoIcons(getPokemon(fusedDexNum),viewport) if @draw_sprite_info
end
def initializeSelectArrow
@sprites["arrow"] = IconSprite.new(0, 0, @viewport)
@sprites["arrow"].setBitmap(ARROW_GRAPHICS_PATH)
@sprites["arrow"].x = SELECT_ARROW_X_LEFT
@sprites["arrow"].y = SELECT_ARROW_Y_SELECT
@sprites["arrow"].z = 100001
end
def initializeCancelButton()
@sprites["cancel"] = IconSprite.new(0, 0, @viewport)
@sprites["cancel"].setBitmap(CANCEL_BUTTON_PATH)
@sprites["cancel"].x = CANCEL_BUTTON_X
@sprites["cancel"].y = CANCEL_BUTTON_Y
@sprites["cancel"].z = 100000
end
def initializeBackground()
@sprites["background"] = IconSprite.new(0, 0, @viewport)
@sprites["background"].setBitmap(getBackgroundPicture)
@sprites["background"].x = 0
@sprites["background"].y = 0
@sprites["background"].z = 99999
end
def drawFusionPreviewText(viewport, text, x, y)
label_base_color = Color.new(248, 248, 248)
label_shadow_color = Color.new(104, 104, 104)
overlay = BitmapSprite.new(Graphics.width, Graphics.height, viewport).bitmap
textpos = [[text, x, y, 0, label_base_color, label_shadow_color]]
pbDrawTextPositions(overlay, textpos)
end
#todo
# Adds the icons indicating if the fusion has alt sprites and if the final evo has a custom sprite
# also add a second icon to indidcate if the final evolution has a custom
def drawSpriteInfoIcons(fusedPokemon, viewport)
#pokedexUtils = PokedexUtils.new
#hasAltSprites = pokedexUtils.pbGetAvailableAlts(fusedPokemon).size>1
#pokedexUtils.getFinalEvolution(fusedPokemon).real_name
#todo
end
def dispose
@picture1.dispose
@picture2.dispose
for typeWindow in @typewindows
typeWindow.dispose
end
pbDisposeSpriteHash(@sprites)
end
def drawPokemonType(pokemon_id, viewport, x_pos = 192, y_pos = 264)
width = 66
viewport.z = 1000001
overlay = BitmapSprite.new(Graphics.width, Graphics.height, viewport).bitmap
pokemon = GameData::Species.get(pokemon_id)
typebitmap = AnimatedBitmap.new(_INTL("Graphics/Pictures/types"))
echoln pokemon
echoln pokemon.types
echoln pokemon.id
type1_number = GameData::Type.get(pokemon.type1).icon_position
type2_number = GameData::Type.get(pokemon.type2).icon_position if pokemon.type2
type1rect = Rect.new(0, type1_number * 28, 64, 28)
type2rect = Rect.new(0, type2_number * 28, 64, 28)
if pokemon.type1 == pokemon.type2
overlay.blt(x_pos + (width / 2), y_pos, typebitmap.bitmap, type1rect)
else
overlay.blt(x_pos, y_pos, typebitmap.bitmap, type1rect)
overlay.blt(x_pos + width, y_pos, typebitmap.bitmap, type2rect)
end
return viewport
end
end

View File

@@ -0,0 +1,290 @@
def getPokemonPositionInParty(pokemon)
for i in 0..$player.party.length
if $player.party[i] == pokemon
return i
end
end
return -1
end
# don't remember why there's two Supersplicers arguments.... probably a mistake
def pbDNASplicing(pokemon, scene, item = :DNASPLICERS)
echoln pokemon
echoln scene
echoln item
is_supersplicer = isSuperSplicersMechanics(item)
playingBGM = $game_system.getPlayingBGM
if (pokemon.species_data.id_number <= Settings::NB_POKEMON)
chosen = scene.pbChoosePokemon(_INTL("Fuse with which Pokémon?"))
if chosen >= 0
poke2 = $player.party[chosen]
if (poke2.species_data.id_number <= Settings::NB_POKEMON) && poke2 != pokemon
# check if fainted
if pokemon.egg? || poke2.egg?
scene.pbDisplay(_INTL("It's impossible to fuse an egg!"))
return false
end
if pokemon.hp == 0 || poke2.hp == 0
scene.pbDisplay(_INTL("A fainted Pokémon cannot be fused!"))
return false
end
selectedHead = selectFusion(pokemon, poke2, is_supersplicer)
if selectedHead == -1 # cancelled
return false
end
if selectedHead == nil # can't fuse (egg, etc.)
scene.pbDisplay(_INTL("It won't have any effect."))
return false
end
selectedBase = selectedHead == pokemon ? poke2 : pokemon
firstOptionSelected = selectedHead == pokemon
if !firstOptionSelected
chosen = getPokemonPositionInParty(pokemon)
if chosen == -1
scene.pbDisplay(_INTL("There was an error..."))
return false
end
end
if (Kernel.pbConfirmMessage(_INTL("Fuse {1} and {2}?", selectedHead.name, selectedBase.name)))
pbFuse(selectedHead, selectedBase, item)
$Trainer.remove_pokemon_at_index(chosen)
scene.pbHardRefresh
pbBGMPlay(playingBGM)
return true
end
elsif pokemon == poke2
scene.pbDisplay(_INTL("{1} can't be fused with itself!", pokemon.name))
return false
else
scene.pbDisplay(_INTL("{1} can't be fused with {2}.", poke2.name, pokemon.name))
return false
end
else
return false
end
else
# UNFUSE
return true if pbUnfuse(pokemon, scene, is_supersplicer)
end
end
def selectFusion(pokemon, poke2, supersplicers = false)
return nil if !pokemon.is_a?(Pokemon) || !poke2.is_a?(Pokemon)
return nil if pokemon.egg? || poke2.egg?
selectorWindow = FusionPreviewScreen.new(poke2, pokemon, supersplicers) # PictureWindow.new(picturePath)
selectedHead = selectorWindow.getSelection
selectorWindow.dispose
return selectedHead
end
def pbFuse(pokemon_body, pokemon_head, splicer_item)
use_supersplicers_mechanics = isSuperSplicersMechanics(splicer_item)
newid = (pokemon_body.species_data.id_number) * Settings::NB_POKEMON + pokemon_head.species_data.id_number
fus = PokemonFusionScene.new
if (fus.pbStartScreen(pokemon_body, pokemon_head, newid, splicer_item))
returnItemsToBag(pokemon_body, pokemon_head)
fus.pbFusionScreen(false, use_supersplicers_mechanics)
$game_variables[VAR_FUSE_COUNTER] += 1 # fuse counter
fus.pbEndScreen
return true
end
end
# Todo: refactor this, holy shit this is a mess
def pbUnfuse(pokemon, scene, supersplicers, pcPosition = nil)
if pokemon.species_data.id_number > (Settings::NB_POKEMON * Settings::NB_POKEMON) + Settings::NB_POKEMON # triple fusion
scene.pbDisplay(_INTL("{1} cannot be unfused.", pokemon.name))
return false
end
if pokemon.owner.name == "RENTAL"
scene.pbDisplay(_INTL("You cannot unfuse a rental pokémon!"))
return
end
pokemon.spriteform_body = nil
pokemon.spriteform_head = nil
bodyPoke = getBasePokemonID(pokemon.species_data.id_number, true)
headPoke = getBasePokemonID(pokemon.species_data.id_number, false)
if (pokemon.foreign?($player)) # && !canunfuse
scene.pbDisplay(_INTL("You can't unfuse a Pokémon obtained in a trade!"))
return false
else
if Kernel.pbConfirmMessageSerious(_INTL("Should {1} be unfused?", pokemon.name))
keepInParty = 0
if $player.party.length >= 6 && !pcPosition
message = "Your party is full! Keep which Pokémon in party?"
message = "Your party is full! Keep which Pokémon in party? The other will be released." if isOnPinkanIsland()
scene.pbDisplay(_INTL(message))
selectPokemonMessage = "Select a Pokémon to keep in your party."
selectPokemonMessage = "Select a Pokémon to keep in your party. The other will be released" if isOnPinkanIsland()
choice = Kernel.pbMessage(selectPokemonMessage, [_INTL("{1}", PBSpecies.getName(bodyPoke)), _INTL("{1}", PBSpecies.getName(headPoke)), "Cancel"], 2)
if choice == 2
return false
else
keepInParty = choice
end
end
scene.pbDisplay(_INTL("Unfusing ... "))
scene.pbDisplay(_INTL(" ... "))
scene.pbDisplay(_INTL(" ... "))
if pokemon.exp_when_fused_head == nil || pokemon.exp_when_fused_body == nil
new_level = calculateUnfuseLevelOldMethod(pokemon, supersplicers)
body_level = new_level
head_level = new_level
poke1 = Pokemon.new(bodyPoke, body_level)
poke2 = Pokemon.new(headPoke, head_level)
else
exp_body = pokemon.exp_when_fused_body + pokemon.exp_gained_since_fused
exp_head = pokemon.exp_when_fused_head + pokemon.exp_gained_since_fused
poke1 = Pokemon.new(bodyPoke, pokemon.level)
poke2 = Pokemon.new(headPoke, pokemon.level)
poke1.exp = exp_body
poke2.exp = exp_head
end
body_level = poke1.level
head_level = poke2.level
pokemon.exp_gained_since_fused = 0
pokemon.exp_when_fused_head = nil
pokemon.exp_when_fused_body = nil
if pokemon.shiny?
pokemon.shiny = false
if pokemon.bodyShiny? && pokemon.headShiny?
pokemon.shiny = true
poke2.shiny = true
pokemon.natural_shiny = true if pokemon.natural_shiny && !pokemon.debug_shiny
poke2.natural_shiny = true if pokemon.natural_shiny && !pokemon.debug_shiny
elsif pokemon.bodyShiny?
pokemon.shiny = true
poke2.shiny = false
pokemon.natural_shiny = true if pokemon.natural_shiny && !pokemon.debug_shiny
elsif pokemon.headShiny?
poke2.shiny = true
pokemon.shiny = false
poke2.natural_shiny = true if pokemon.natural_shiny && !pokemon.debug_shiny
else
# shiny was obtained already fused
if rand(2) == 0
pokemon.shiny = true
else
poke2.shiny = true
end
end
end
fused_pokemon_learned_moved = pokemon.learned_moves
pokemon.learned_moves = fused_pokemon_learned_moved
poke2.learned_moves = fused_pokemon_learned_moved
pokemon.ability_index = pokemon.body_original_ability_index if pokemon.body_original_ability_index
poke2.ability_index = pokemon.head_original_ability_index if pokemon.head_original_ability_index
pokemon.ability2_index = nil
pokemon.ability2 = nil
poke2.ability2_index = nil
poke2.ability2 = nil
pokemon.debug_shiny = true if pokemon.debug_shiny && pokemon.body_shiny
poke2.debug_shiny = true if pokemon.debug_shiny && poke2.head_shiny
pokemon.body_shiny = false
pokemon.head_shiny = false
if !pokemon.shiny?
pokemon.debug_shiny = false
end
if !poke2.shiny?
poke2.debug_shiny = false
end
if $player.party.length >= 6
if (keepInParty == 0)
if isOnPinkanIsland()
scene.pbDisplay(_INTL("{1} was released.", poke2.name))
else
$PokemonStorage.pbStoreCaught(poke2)
scene.pbDisplay(_INTL("{1} was sent to the PC.", poke2.name))
end
else
poke2 = Pokemon.new(bodyPoke, body_level)
poke1 = Pokemon.new(headPoke, head_level)
# Fusing from PC
if pcPosition != nil
box = pcPosition[0]
index = pcPosition[1]
# todo: store at next available position from current position
$PokemonStorage.pbStoreCaught(poke2)
else
# Fusing from party
if isOnPinkanIsland()
scene.pbDisplay(_INTL("{1} was released.", poke2.name))
else
$PokemonStorage.pbStoreCaught(poke2)
scene.pbDisplay(_INTL("{1} was sent to the PC.", poke2.name))
end
end
end
else
if pcPosition != nil
box = pcPosition[0]
index = pcPosition[1]
# todo: store at next available position from current position
$PokemonStorage.pbStoreCaught(poke2)
else
Kernel.pbAddPokemonSilent(poke2, poke2.level)
end
end
# On ajoute les poke au pokedex
$player.pokedex.set_seen(poke1.species)
$player.pokedex.set_owned(poke1.species)
$player.pokedex.set_seen(poke2.species)
$player.pokedex.set_owned(poke2.species)
pokemon.species = poke1.species
pokemon.level = poke1.level
pokemon.name = poke1.name
pokemon.moves = poke1.moves
pokemon.obtain_method = 0
poke1.obtain_method = 0
# scene.pbDisplay(_INTL(p1.to_s + " " + p2.to_s))
scene.pbHardRefresh
scene.pbDisplay(_INTL("Your Pokémon were successfully unfused! "))
return true
end
end
end# frozen_string_literal: true
def returnItemsToBag(pokemon, poke2)
it1 = pokemon.item
it2 = poke2.item
$PokemonBag.pbStoreItem(it1, 1) if it1 != nil
$PokemonBag.pbStoreItem(it2, 1) if it2 != nil
pokemon.item = nil
poke2.item = nil
end

View File

@@ -0,0 +1,421 @@
module GameData
class FusedSpecies < GameData::Species
attr_reader :growth_rate
attr_reader :body_pokemon
attr_reader :head_pokemon
def initialize(id)
if id.is_a?(Integer)
body_id = getBodyID(id)
head_id = getHeadID(id, body_id)
pokemon_id = getFusedPokemonIdFromDexNum(body_id, head_id)
return GameData::FusedSpecies.new(pokemon_id)
end
head_id = get_head_number_from_symbol(id)
body_id = get_body_number_from_symbol(id)
@body_pokemon = GameData::Species.get(body_id)
@head_pokemon = GameData::Species.get(head_id)
@id = id
@id_number = calculate_dex_number()
@species = @id
@form = 0
@real_name = calculate_name()
@real_form_name = nil
@type1 = calculate_type1()
@type2 = calculate_type2()
@types = [@type1, @type2]
#Stats
@base_stats = calculate_base_stats()
@evs = calculate_evs()
adjust_stats_with_evs()
@base_exp = calculate_base_exp()
@growth_rate = calculate_growth_rate()
@gender_ratio = calculate_gender() #todo
@catch_rate = calculate_catch_rate()
@happiness = calculate_base_happiness()
#Moves
@moves = calculate_moveset()
@tutor_moves = calculate_tutor_moves() # hash[:tutor_moves] || []
@egg_moves = calculate_egg_moves() # hash[:egg_moves] || []
#Abilities
@abilities = calculate_abilities() # hash[:abilities] || []
@hidden_abilities = calculate_hidden_abilities() # hash[:hidden_abilities] || []
#wild held items
@wild_item_common = get_wild_item(@head_pokemon.wild_item_common, @body_pokemon.wild_item_common) # hash[:wild_item_common]
@wild_item_uncommon = get_wild_item(@head_pokemon.wild_item_uncommon, @body_pokemon.wild_item_uncommon) # hash[:wild_item_uncommon]
@wild_item_rare = get_wild_item(@head_pokemon.wild_item_rare, @body_pokemon.wild_item_rare) # hash[:wild_item_rare]
@evolutions = calculate_evolutions() # hash[:evolutions] || []
#breeding
@egg_groups = [:Undiscovered] #calculate_egg_groups() # hash[:egg_groups] || [:Undiscovered]
@hatch_steps = calculate_hatch_steps() # hash[:hatch_steps] || 1
@incense = nil #hash[:incense]
#pokedex
@pokedex_form = @form #ignored
@real_category = calculate_category()
@real_pokedex_entry = calculate_dex_entry()
@height = average_values(@head_pokemon.height, @body_pokemon.height)
@weight = average_values(@head_pokemon.weight, @body_pokemon.weight)
@color = @head_pokemon.color
@shape = @body_pokemon.shape
#sprite positioning
#todo: this was moved to pokemon_metrics
# read the data for the body pokemon's species whenever it tries to position a fusedSpecies
#
# @back_sprite_x = @body_pokemon.back_sprite_x
# @back_sprite_y = @body_pokemon.back_sprite_y
# @front_sprite_x = @body_pokemon.front_sprite_x
# @front_sprite_y = @body_pokemon.front_sprite_y
# @front_sprite_altitude = @body_pokemon.front_sprite_altitude
# @shadow_x = @body_pokemon.shadow_x
# @shadow_size = @body_pokemon.shadow_size
# #unused attributes from Species class
#
# @shape = :Head
# @habitat = :None
# @generation = 0
# @mega_stone = nil
# @mega_move = nil
# @unmega_form = 0
# @mega_message = 0
end
def type1
return @type1
end
def type2
return @type2
end
def apply_metrics_to_sprite(sprite, index, shadow = false)
body_species = get_body_species()
metrics_data = GameData::SpeciesMetrics.get_species_form(body_species, 0)
metrics_data.apply_metrics_to_sprite(sprite, index, shadow)
end
def get_body_number_from_symbol(id)
return id.to_s.match(/\d+/)[0].to_i
end
def get_head_number_from_symbol(id)
return id.to_s.match(/(?<=H)\d+/)[0].to_i
end
def get_body_species
return @body_pokemon.id_number
end
def get_head_species
return @head_pokemon.id_number
end
def get_body_species_symbol
return @body_pokemon.id
end
def get_head_species_symbol
return @head_pokemon.id
end
def adjust_stats_with_evs
GameData::Stat.each_main do |s|
@base_stats[s.id] = 1 if !@base_stats[s.id] || @base_stats[s.id] <= 0
@evs[s.id] = 0 if !@evs[s.id] || @evs[s.id] < 0
end
end
#FUSION CALCULATIONS
def calculate_dex_number()
return (@body_pokemon.id_number * Settings::NB_POKEMON) + @head_pokemon.id_number
end
def calculate_type1()
return @head_pokemon.type2 if @head_pokemon.type1 == :NORMAL && @head_pokemon.type2 == :FLYING
return @head_pokemon.type1
end
def calculate_type2()
return @body_pokemon.type1 if @body_pokemon.type2 == @type1
return @body_pokemon.type2
end
def calculate_base_stats()
head_stats = @head_pokemon.base_stats
body_stats = @body_pokemon.base_stats
fused_stats = {}
#Head dominant stats
fused_stats[:HP] = calculate_fused_stats(head_stats[:HP], body_stats[:HP])
fused_stats[:SPECIAL_DEFENSE] = calculate_fused_stats(head_stats[:SPECIAL_DEFENSE], body_stats[:SPECIAL_DEFENSE])
fused_stats[:SPECIAL_ATTACK] = calculate_fused_stats(head_stats[:SPECIAL_ATTACK], body_stats[:SPECIAL_ATTACK])
#Body dominant stats
fused_stats[:ATTACK] = calculate_fused_stats(body_stats[:ATTACK], head_stats[:ATTACK])
fused_stats[:DEFENSE] = calculate_fused_stats(body_stats[:DEFENSE], head_stats[:DEFENSE])
fused_stats[:SPEED] = calculate_fused_stats(body_stats[:SPEED], head_stats[:SPEED])
return fused_stats
end
def calculate_base_exp()
head_exp = @head_pokemon.base_exp
body_exp = @body_pokemon.base_exp
return average_values(head_exp, body_exp)
end
def calculate_catch_rate
return get_lowest_value(@body_pokemon.catch_rate, @head_pokemon.catch_rate)
end
def calculate_base_happiness
return @head_pokemon.happiness
end
def calculate_moveset
return combine_arrays(@body_pokemon.moves, @head_pokemon.moves)
end
def calculate_egg_moves
return combine_arrays(@body_pokemon.egg_moves, @head_pokemon.egg_moves)
end
def calculate_tutor_moves
return combine_arrays(@body_pokemon.tutor_moves, @head_pokemon.tutor_moves)
end
def get_wild_item(body_item, head_item)
rand_num = rand(2)
if rand_num == 0
return body_item
else
return head_item
end
end
def calculate_abilities()
abilities_hash = []
ability1 = @body_pokemon.abilities[0]
ability2 = @head_pokemon.abilities[0]
abilities_hash << ability1
abilities_hash << ability2
return abilities_hash
end
# def calculate_abilities(pokemon1, pokemon2)
# abilities_hash = []
#
# ability1 = pokemon1.abilities[0]
# ability2 = pokemon2.abilities[1]
# if !ability2
# ability2 = pokemon2.abilities[0]
# end
# abilities_hash << ability1
# abilities_hash << ability2
# return abilities_hash
# end
def calculate_hidden_abilities()
abilities_hash = []
#First two spots are the other abilities of the two pokemon
ability1 = @body_pokemon.abilities[1]
ability2 = @head_pokemon.abilities[1]
ability1 = @body_pokemon.abilities[0] if !ability1
ability2 = @head_pokemon.abilities[0] if !ability2
abilities_hash << ability1
abilities_hash << ability2
#add the hidden ability for the two base pokemon
hiddenAbility1 = @body_pokemon.hidden_abilities[0]
hiddenAbility1 = ability1 if !hiddenAbility1
hiddenAbility2 = @head_pokemon.hidden_abilities[0]
hiddenAbility2 = ability2 if !hiddenAbility2
abilities_hash << hiddenAbility1
abilities_hash << hiddenAbility2
return abilities_hash
end
def calculate_name()
body_nat_dex = GameData::NAT_DEX_MAPPING[@body_pokemon.id_number] ? GameData::NAT_DEX_MAPPING[@body_pokemon.id_number] : @body_pokemon.id_number
head_nat_dex = GameData::NAT_DEX_MAPPING[@head_pokemon.id_number] ? GameData::NAT_DEX_MAPPING[@head_pokemon.id_number] : @head_pokemon.id_number
begin
prefix = GameData::SPLIT_NAMES[head_nat_dex][0]
suffix = GameData::SPLIT_NAMES[body_nat_dex][1]
if prefix[-1] == suffix[0]
prefix = prefix[0..-2]
end
suffix = suffix.capitalize if prefix.end_with?(" ")
return prefix + suffix
rescue
print("species with error: " + @species.to_s)
end
end
def calculate_evolutions()
body_evolutions = @body_pokemon.evolutions
head_evolutions = @head_pokemon.evolutions
fused_evolutions = []
#body
for evolution in body_evolutions
evolutionSpecies = evolution[0]
evolutionSpecies_dex = GameData::Species.get(evolutionSpecies).id_number
fused_species = _INTL("B{1}H{2}", evolutionSpecies_dex, @head_pokemon.id_number)
fused_evolutions << build_evolution_array(evolution, fused_species)
end
#head
for evolution in head_evolutions
evolutionSpecies = evolution[0]
evolutionSpecies_dex = GameData::Species.get(evolutionSpecies).id_number
fused_species = _INTL("B{1}H{2}", @body_pokemon.id_number, evolutionSpecies_dex)
fused_evolutions << build_evolution_array(evolution, fused_species)
end
return fused_evolutions
end
#Change the evolution species depending if head & body and keep the rest of the data the same
def build_evolution_array(evolution_data, new_species)
fused_evolution_array = []
fused_evolution_array << new_species.to_sym
#add the rest
for data in evolution_data
next if evolution_data.index(data) == 0
fused_evolution_array << data
end
return fused_evolution_array
end
def calculate_dex_entry
body_entry = @body_pokemon.real_pokedex_entry.gsub(@body_pokemon.real_name, @real_name)
head_entry = @head_pokemon.real_pokedex_entry.gsub(@head_pokemon.real_name, @real_name)
return split_and_combine_text(body_entry, head_entry, ".")
end
def get_random_dex_entry()
begin
file_path = Settings::POKEDEX_ENTRIES_PATH
json_data = File.read(file_path)
all_body_entries = HTTPLite::JSON.parse(json_data)
body_entry = all_body_entries[@body_pokemon.id_number.to_s].sample
body_entry = body_entry.gsub(/#{@body_pokemon.real_name}/i, @real_name)
body_entry = clean_json_string(body_entry).gsub(@body_pokemon.real_name, @real_name)
head_entry = all_body_entries[@head_pokemon.id_number.to_s].sample
head_entry = head_entry.gsub(/#{@head_pokemon.real_name}/i, @real_name)
head_entry = clean_json_string(head_entry).gsub(@head_pokemon.real_name, @real_name)
rescue
body_entry = @body_pokemon.real_pokedex_entry.gsub(@body_pokemon.real_name, @real_name)
head_entry = @head_pokemon.real_pokedex_entry.gsub(@head_pokemon.real_name, @real_name)
end
echoln body_entry
echoln head_entry
combined_entry = split_and_combine_text(body_entry, head_entry, ".")
combined_entry += "." unless combined_entry.end_with?(".")
return combined_entry
end
def calculate_egg_groups
body_egg_groups = @body_pokemon.egg_groups
head_egg_groups = @head_pokemon.egg_groups
return :Undiscovered if body_egg_groups.include?(:Undiscovered) || head_egg_groups.include?(:Undiscovered)
return combine_arrays(body_egg_groups, head_egg_groups)
end
def calculate_hatch_steps
return average_values(@head_pokemon.hatch_steps, @body_pokemon.hatch_steps)
end
def calculate_evs()
return average_map_values(@body_pokemon.evs, @head_pokemon.evs)
end
def calculate_category
return split_and_combine_text(@body_pokemon.category, @head_pokemon.category, " ")
end
def calculate_growth_rate
growth_rate_priority = [:Fast, :Medium, :Parabolic, :Fluctuating, :Erratic, :Slow] #todo rearrange order for balance?
body_growth_rate = @body_pokemon.growth_rate
head_growth_rate = @head_pokemon.growth_rate
base_growth_rates = [body_growth_rate, head_growth_rate]
for rate in growth_rate_priority
return rate if base_growth_rates.include?(rate)
end
return :Medium
end
#TODO
# ################## UNFINISHED ####################
def calculate_gender
return :Genderless
end
############################# UTIL METHODS ###############################
#Takes 2 strings, splits and combines them using the beginning of the first one and the end of the second one
# (for example for pokedex entries)
def split_and_combine_text(beginingText_full, endText_full, separator)
beginingText_split = beginingText_full.split(separator, 2)
endText_split = endText_full.split(separator, 2)
beginningText = beginingText_split[0]
endText = endText_split[1] && endText_split[1] != "" ? endText_split[1] : endText_split[0]
return beginningText + separator + " " + endText
end
def calculate_fused_stats(dominantStat, otherStat)
return ((2 * dominantStat) / 3) + (otherStat / 3).floor
end
def average_values(value1, value2)
return ((value1 + value2) / 2).floor
end
def average_map_values(map1, map2)
averaged_map = map1.merge(map2) do |key, value1, value2|
((value1 + value2) / 2.0).floor
end
return averaged_map
end
def get_highest_value(value1, value2)
return value1 > value2 ? value1 : value2
end
def get_lowest_value(value1, value2)
return value1 < value2 ? value1 : value2
end
def combine_arrays(array1, array2)
return array1 + array2
end
end
end

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,74 @@
module GameData
module ClassMethods
def get(other)
validate other => [Symbol, self, String, Integer]
return other if other.is_a?(self)
other = other.to_sym if other.is_a?(String)
if other.to_s.match?(/\AB\d+H\d+\z/)
species = GameData::FusedSpecies.new(other)
return species
end
if other.is_a?(Integer) && self == GameData::Species
if other > Settings::NB_POKEMON
body_id = getBodyID(other)
head_id = getHeadID(other, body_id)
pokemon_id = getFusedPokemonIdFromDexNum(body_id, head_id)
return GameData::FusedSpecies.new(pokemon_id)
else
species_id = GameData::Species.keys[other-1]
return GameData::Species.get(species_id) if species_id
end
end
if !self::DATA.has_key?(other)
# echoln _INTL("Unknown ID {1}.", other)
return self::get(:PIKACHU)
end
raise "Unknown ID #{other}." unless self::DATA.has_key?(other)
return self::DATA[other]
end
end
module ClassMethodsSymbols
def get(other)
validate other => [Symbol, self, String, Integer]
return other if other.is_a?(self)
other = other.to_sym if other.is_a?(String)
if other.to_s.match?(/\AB\d+H\d+\z/)
species = GameData::FusedSpecies.new(other)
return species
end
if other.is_a?(Integer) && self == GameData::Species
if other > Settings::NB_POKEMON
body_id = getBodyID(other)
head_id = getHeadID(other, body_id)
pokemon_id = getFusedPokemonIdFromDexNum(body_id, head_id)
return GameData::FusedSpecies.new(pokemon_id)
else
species_id = GameData::Species.keys[other-1]
return GameData::Species.get(species_id) if species_id
end
end
raise "Unknown ID #{other}." unless self::DATA.has_key?(other)
return self::DATA[other]
end
def try_get(other)
return nil 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] : nil
end
end
end

View File

@@ -0,0 +1,38 @@
# class PokemonFusionScene
# HEAD_SPRITE_STARTING_POS = Graphics.width / 2
#
#
# def pbStartScreen(pokemon_head,pokemon_body,pokemon_fused)
#
# @pokemon_head = pokemon_head
# @pokemon_body = pokemon_body
#
# @pokemon_fused = pokemon_fused
#
# @sprites = {}
# @viewport = Viewport.new(0, 0, Graphics.width, Graphics.height)
# @viewport.z = 99999
#
# initialize_background()
# initialize_sprites()
# end
#
# def initialize_background()
# addBackgroundOrColoredPlane(@sprites, "background", "DNAbg",
# Color.new(248, 248, 248), @viewport)
# end
#
# def initialize_sprites()
# pokeHead_number = GameData::Species.get(@pokemon_head.species).id_number
# pokeBody_number = GameData::Species.get(@pokemon_body.species).id_number
#
# @sprites["poke_head"] = PokemonSprite.new(@viewport)
# @sprites["poke_head"].setPokemonBitmapFromId(pokeHead_number, false, @pokemon_head.shiny?)
#
# @sprites["poke_head"].ox = @sprites["rsprite1"].bitmap.width / 2
# @sprites["poke_head"].x = Graphics.width / 2
# @sprites["poke_head"].zoom_x = Settings::FRONTSPRITE_SCALE
#
# end
#
# end

View File

@@ -0,0 +1,115 @@
class FusionSelectOptionsScene < PokemonOption_Scene
attr_accessor :selectedAbility
attr_accessor :selectedNature
attr_accessor :hasNickname
attr_accessor :nickname
def initialize(abilityList,natureList, pokemon1, pokemon2)
@abilityList = abilityList
@natureList = natureList
@selectedAbility=nil
@selectedNature=nil
@selBaseColor = Color.new(48,96,216)
@selShadowColor = Color.new(32,32,32)
@show_frame=false
@hasNickname = false
@nickname = nil
@pokemon1=pokemon1
@pokemon2=pokemon2
end
def initUIElements
@sprites["title"] = Window_UnformattedTextPokemon.newWithSize(
_INTL("Select your Pokémon's ability and nature"), 0, 0, Graphics.width, 64, @viewport)
@sprites["textbox"] = pbCreateMessageWindow
@sprites["textbox"].letterbyletter = false
pbSetSystemFont(@sprites["textbox"].contents)
@sprites["title"].opacity=0
end
def pbStartScene(inloadscreen = nil)
super
@sprites["option"].opacity=0
end
def getAbilityName(ability)
return GameData::Ability.get(ability.id).real_name
end
def getAbilityDescription(ability)
return GameData::Ability.get(ability.id).real_description
end
def getNatureName(nature)
return GameData::Nature.get(nature.id).real_name
end
def getNatureDescription(nature)
change= GameData::Nature.get(nature.id).stat_changes
return "Neutral nature" if change.empty?
positiveChange = change[0]
negativeChange = change[1]
return _INTL("+ {1}\n- {2}",GameData::Stat.get(positiveChange[0]).name,GameData::Stat.get(negativeChange[0]).name)
end
def shouldSelectNickname
if @pokemon1.nicknamed? && @pokemon2.nicknamed?
@hasNickname=true
return true
end
if @pokemon1.nicknamed? && !@pokemon2.nicknamed?
@hasNickname=true
@nickname = @pokemon1.name
return false
end
if !@pokemon1.nicknamed? && @pokemon2.nicknamed?
@hasNickname=true
@nickname = @pokemon2.name
return false
end
@hasNickname=false
return false
end
def pbGetOptions(inloadscreen = false)
options = []
if shouldSelectNickname
options << EnumOption.new(_INTL("Nickname"), [_INTL(@pokemon1.name), _INTL(@pokemon2.name)],
proc { 0 },
proc { |value|
if value ==0
@nickname = @pokemon1.name
else
@nickname = @pokemon2.name
end
}, "Select the Pokémon's nickname")
end
options << EnumOption.new(_INTL("Ability"), [_INTL(getAbilityName(@abilityList[0])), _INTL(getAbilityName(@abilityList[1]))],
proc { 0 },
proc { |value|
@selectedAbility=@abilityList[value]
}, [getAbilityDescription(@abilityList[0]), getAbilityDescription(@abilityList[1])]
)
options << EnumOption.new(_INTL("Nature"), [_INTL(getNatureName(@natureList[0])), _INTL(getNatureName(@natureList[1]))],
proc { 0 },
proc { |value|
@selectedNature=@natureList[value]
}, [getNatureDescription(@natureList[0]), getNatureDescription(@natureList[1])]
)
return options
end
def isConfirmedOnKeyPress
return true
end
end

View File

@@ -0,0 +1,39 @@
class FusionPreviewScreen < DoublePreviewScreen
attr_reader :poke1
attr_reader :poke2
attr_reader :fusedPokemon
attr_reader :fusedPokemon
attr_writer :draw_types
attr_writer :draw_level
BACKGROUND_PATH = "Graphics/Pictures/DNAbg"
def initialize(poke1,poke2, usingSuperSplicers=false)
super(poke1,poke2)
@draw_types = true
@draw_level = true
@draw_sprite_info=true
#@viewport = viewport
@poke1 = poke1
@poke2 = poke2
@fusedPokemon=nil
new_level = calculateFusedPokemonLevel(poke1.level, poke2.level, usingSuperSplicers)
fusion_left = (poke1.species_data.id_number) * Settings::NB_POKEMON + poke2.species_data.id_number
fusion_right = (poke2.species_data.id_number) * Settings::NB_POKEMON + poke1.species_data.id_number
@picture1 = draw_window(fusion_left,new_level,20,30)
@picture2 = draw_window(fusion_right,new_level,270,30)
@sprites["picture1"] = @picture1
@sprites["picture2"] = @picture2
end
def getBackgroundPicture
super
end
end

View File

@@ -0,0 +1,453 @@
class Pokemon
attr_accessor :exp_when_fused_head
attr_accessor :exp_when_fused_body
attr_accessor :exp_gained_since_fused
attr_accessor :hat
attr_accessor :hat_x
attr_accessor :hat_y
attr_accessor :glitter
attr_accessor :head_shiny
attr_accessor :body_shiny
attr_accessor :debug_shiny
attr_accessor :natural_shiny
attr_writer :ability_index
attr_accessor :body_original_ability_index
attr_accessor :head_original_ability_index
# @return [Array<Symbol>] All the move (ids) ever learned by this Pokémon
attr_accessor :learned_moves
attr_accessor :force_disobey
def print_all_attributes
instance_variables.each do |var|
begin
value = instance_variable_get(var)
echoln("#{var}: #{value.inspect}")
rescue => e
echoln("#{var}: [Error reading value: #{e.message}]")
end
end
end
def id_number
return species_data.id_number
end
def hiddenPower=(type)
@hiddenPowerType = type
end
def sprite_scale()
@sprite_scale = 1 if !@sprite_scale
return @sprite_scale
end
def sprite_scale=(scale)
@sprite_scale = scale
end
def size_category()
@size_category = :AVERAGE if !@size_category
return @size_category
end
def size_category=(category)
@size_category = category
end
def hasBodyOf?(check_species)
if !self.isFusion?
return isSpecies?(check_species)
end
bodySpecies = getBodyID(species)
checkSpeciesId = getID(nil, check_species)
return bodySpecies == checkSpeciesId
end
def hasHeadOf?(check_species)
if !self.isFusion?
return isSpecies?(check_species)
end
headSpecies = getHeadID(species)
checkSpeciesId = getID(nil, check_species)
return headSpecies == checkSpeciesId
end
def head_id()
return get_head_id_from_symbol(@species)
end
def body_id()
return get_body_id_from_symbol(@species)
end
def shiny=(value)
@shiny = value
if value && Settings::SHINY_POKEMON_CHANCE != S_CHANCE_VALIDATOR
@debug_shiny = true
end
end
def isShiny?()
return @shiny || @body_shiny || @head_shiny
end
def naturalShiny?
return @natural_shiny
end
def debugShiny?
return !@natural_shiny || @debug_shiny
end
def bodyShiny?
return @body_shiny
end
def headShiny?
return @head_shiny
end
def isFusionOf(check_species)
return hasBodyOf?(check_species) || hasHeadOf?(check_species)
end
def dexNum
return species_data.id_number
end
def isSelfFusion?
return isFusion? && getHeadID(species) == getBodyID(species)
end
def isFusion?
return species_data.id_number > NB_POKEMON && !self.isTripleFusion?
end
def isTripleFusion?
return species_data.id_number >= Settings::ZAPMOLCUNO_NB
end
def changeFormSpecies(oldForm, newForm)
is_already_old_form = self.isFusionOf(oldForm) #A 466
is_already_new_form = self.isFusionOf(newForm) #P
#reverse the fusion if it's a meloA and meloP fusion
# There's probably a smarter way to do this but laziness lol
if is_already_old_form && is_already_new_form
body_id = self.species_data.get_body_species()
body_species = GameData::Species.get(body_id)
if body_species == oldForm
changeSpeciesSpecific(self, getFusedPokemonIdFromSymbols(newForm, oldForm))
else
changeSpeciesSpecific(self, getFusedPokemonIdFromSymbols(oldForm, newForm))
end
else
echoln "changing species...."
changeSpecies(self, oldForm, newForm) if is_already_old_form
changeSpecies(self, newForm, oldForm) if is_already_new_form
end
calc_stats
end
def changeSpecies(pokemon, speciesToReplace, newSpecies)
if pokemon.isFusion?()
replaceFusionSpecies(pokemon, speciesToReplace, newSpecies)
else
changeSpeciesSpecific(pokemon, newSpecies)
end
$Trainer.pokedex.set_seen(pokemon.species)
$Trainer.pokedex.set_owned(pokemon.species)
end
def type1
if @ability == :MULTITYPE && species_data.type1 == :NORMAL
return getHeldPlateType()
end
return @type1 if @type1
return species_data.type1
end
# @return [Symbol] this Pokémon's second type, or the first type if none is defined
def type2
if @ability == :MULTITYPE && species_data.type2 == :NORMAL
return getHeldPlateType()
end
sp_data = species_data
return sp_data.type2 || sp_data.type1
end
def type1=(value)
@type1 = value
end
def type2=(value)
@type2 = value
end
def getHeldPlateType()
return getArceusPlateType(@item)
end
def makeMale
@gender = 0
end
# Makes this Pokémon female.
def makeFemale
@gender = 1
end
# @return [Boolean] whether this Pokémon is male
def male?
return self.gender == 0;
end
# @return [Boolean] whether this Pokémon is female
def female?
return self.gender == 1;
end
# @return [Boolean] whether this Pokémon is genderless
def genderless?
return self.gender == 2;
end
def add_learned_move(move)
@learned_moves = [] if !@learned_moves
if move.is_a?(Symbol)
@learned_moves << move unless @learned_moves.include?(move)
else
move_id = move.id
if move_id
@learned_moves << move_id unless @learned_moves.include?(move_id)
end
end
end
alias pokemonEssentials_Pokemon_learn_move learn_move
def learn_move(move)
pokemonEssentials_Pokemon_learn_move(move)
add_learned_move(move)
end
alias pokemonEssentials_Pokemon_forget_move forget_move
def forget_move(move_id)
pokemonEssentials_Pokemon_forget_move(move_id)
add_learned_move(move_id)
end
def forget_move_at_index(index)
move_id = @moves[index].id
add_learned_move(move_id)
@moves.delete_at(index)
end
# Deletes all moves from the Pokémon.
def forget_all_moves
for move in @moves
add_learned_move(move)
end
@moves.clear
end
def compatible_with_move?(move_id)
move_data = GameData::Move.try_get(move_id)
if isFusion?()
head_species_id = getBasePokemonID(species, false)
body_species_id = getBasePokemonID(species)
head_species = GameData::Species.get(head_species_id)
body_species = GameData::Species.get(body_species_id)
return move_data && (pokemon_can_learn_move(head_species, move_data) || pokemon_can_learn_move(body_species, move_data))
else
return move_data && pokemon_can_learn_move(species_data, move_data)
end
end
def pokemon_can_learn_move(species_data, move_data)
moveset = species_data.moves.map { |pair| pair[1] }
return species_data.tutor_moves.include?(move_data.id) ||
species_data.moves.include?(move_data.id) || ##this is formatted as such [[1, :PECK],[etc.]] so it never finds anything when move_data is just the symbol. Leaving it there in case something depends on that for some reason.
moveset.include?(move_data.id) ||
species_data.egg_moves.include?(move_data.id)
end
def has_egg_move?
return false if egg? || shadowPokemon?
baby = pbGetBabySpecies(self.species)
moves = pbGetSpeciesEggMoves(baby)
return true if moves.size >= 1
end
def foreign?(trainer)
return @owner.id != trainer.id# || @owner.name != trainer.name
end
def always_disobey(value)
@force_disobey = value
end
#=============================================================================
# Evolution checks
#=============================================================================
# Checks whether this Pokemon can evolve because of levelling up.
# @return [Symbol, nil] the ID of the species to evolve into
def prompt_evolution_choice(body_evolution, head_evolution)
current_body = @species_data.body_pokemon
current_head = @species_data.head_pokemon
choices = [
#_INTL("Evolve both!"),
_INTL("Evolve head!"),
_INTL("Evolve body!"),
_INTL("Don't evolve")
]
choice = pbMessage(_INTL('Both halves of {1} are ready to evolve!', self.name), choices, 0)
# if choice == 0 #EVOLVE BOTH
# newspecies = getFusionSpecies(body_evolution,head_evolution)
if choice == 0 #EVOLVE HEAD
newspecies = getFusionSpecies(current_body, head_evolution)
elsif choice == 1 #EVOLVE BODY
newspecies = getFusionSpecies(body_evolution, current_head)
else
newspecies = nil
end
return newspecies
end
def check_evolution_on_level_up(prompt_choice=true)
if @species_data.is_a?(GameData::FusedSpecies)
body = self.species_data.body_pokemon
head = self.species_data.head_pokemon
body_evolution = check_evolution_internal(@species_data.body_pokemon) { |pkmn, new_species, method, parameter|
success = GameData::Evolution.get(method).call_level_up(pkmn, parameter)
next (success) ? new_species : nil
}
head_evolution = check_evolution_internal(@species_data.head_pokemon) { |pkmn, new_species, method, parameter|
success = GameData::Evolution.get(method).call_level_up(pkmn, parameter)
next (success) ? new_species : nil
}
if body_evolution && head_evolution
return prompt_evolution_choice(body_evolution, head_evolution) if prompt_choice
return [body_evolution,head_evolution].sample
end
end
return check_evolution_internal { |pkmn, new_species, method, parameter|
success = GameData::Evolution.get(method).call_level_up(pkmn, parameter)
next (success) ? new_species : nil
}
end
def getBaseStatsFormException()
if @species == :PUMPKABOO
case @size_category
when :SMALL
return { :HP => 44, :ATTACK => 66, :DEFENSE => 70, :SPECIAL_ATTACK => 44, :SPECIAL_DEFENSE => 55, :SPEED => 56}
when :AVERAGE
return nil
when :LARGE
return { :HP => 54, :ATTACK => 66, :DEFENSE => 70, :SPECIAL_ATTACK => 44, :SPECIAL_DEFENSE => 55, :SPEED => 46}
when :SUPER
return { :HP => 59, :ATTACK => 66, :DEFENSE => 70, :SPECIAL_ATTACK => 44, :SPECIAL_DEFENSE => 55, :SPEED => 41}
end
end
if @species == :GOURGEIST
case @size_category
when :SMALL
return { :HP => 55, :ATTACK => 85, :DEFENSE => 122, :SPECIAL_ATTACK => 58, :SPECIAL_DEFENSE => 75, :SPEED => 99}
when :AVERAGE
return nil
when :LARGE
return { :HP => 75, :ATTACK => 95, :DEFENSE => 122, :SPECIAL_ATTACK => 58, :SPECIAL_DEFENSE => 75, :SPEED => 69}
when :SUPER
return { :HP => 85, :ATTACK => 100, :DEFENSE => 122, :SPECIAL_ATTACK => 58, :SPECIAL_DEFENSE => 75, :SPEED => 54}
end
end
return nil
end
def adjust_level_for_base_stats_mode()
nb_badges = $Trainer.badge_count
this_level = ((nb_badges * Settings::NO_LEVEL_MODE_LEVEL_INCR) + Settings::NO_LEVEL_MODE_LEVEL_BASE).ceil
if this_level > Settings::MAXIMUM_LEVEL
this_level = Settings::MAXIMUM_LEVEL
end
return this_level
end
def adjustHPForWonderGuard(stats)
return self.ability == :WONDERGUARD ? 1 : stats[:HP]
end
def checkHPRelatedFormChange()
if @ability == :SHIELDSDOWN
return if $game_temp.in_battle #handled in battlers class in-battle
if isFusionOf(:MINIOR_M)
if @hp <= (@totalhp / 2)
changeFormSpecies(:MINIOR_M, :MINIOR_C)
end
end
if isFusionOf(:MINIOR_C)
if @hp > (@totalhp / 2)
changeFormSpecies(:MINIOR_C, :MINIOR_M)
end
end
end
end
def determine_scale
return :AVERAGE if !@size_category
size_roll = rand(100) # Random number between 0-99
if @size_category == :SMALL
return 0.75
elsif @size_category == :AVERAGE
return 1
elsif @size_category == :LARGE
return 1 + (1.0 /3) #"Large Size"
elsif @size_category == :SUPER
return 1 + (2.0 /3) #"Super Size"
end
return 1
end
def determine_size_category
return :AVERAGE if !(Kernel.isPartPokemon(self,:PUMPKABOO) || Kernel.isPartPokemon(self,:GOURGEIST))
size_roll = rand(100) # Random number between 0-99
if size_roll < 10
return :SMALL
elsif size_roll < 50
return :AVERAGE
elsif size_roll < 90
return :LARGE
else
return :SUPER
end
end
def species=(species_id)
new_species_data = GameData::Species.get(species_id)
return if @species == new_species_data.species
@species = new_species_data.species
@forced_form = nil
@gender = nil if singleGendered?
@level = nil # In case growth rate is different for the new species
@ability = nil
calc_stats
end
end

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,420 @@
def is_fusion_of_any(species_id, pokemonList)
is_species = false
for fusionPokemon in pokemonList
if is_fusion_of(species_id, fusionPokemon)
is_species = true
end
end
return is_species
end
def is_fusion_of(checked_species, checked_against)
return species_has_body_of(checked_species, checked_against) || species_has_head_of(checked_species, checked_against)
end
def is_species(checked_species, checked_against)
return checked_species == checked_against
end
def species_has_body_of(checked_species, checked_against)
if !species_is_fusion(checked_species)
return is_species(checked_species, checked_against)
end
bodySpecies = get_body_species_from_symbol(checked_species)
ret = bodySpecies == checked_against
#echoln _INTL("{1} HAS BODY OF {2} : {3} (body is {4})",checked_species,checked_against,ret,bodySpecies)
return ret
end
def species_has_head_of(checked_species, checked_against)
if !species_is_fusion(checked_species)
return is_species(checked_species, checked_against)
end
headSpecies = get_head_species_from_symbol(checked_species)
ret = headSpecies == checked_against
#echoln _INTL("{1} HAS HEAD OF {2} : {3}",checked_species,checked_against,ret)
return ret
end
def species_is_fusion(species_id)
dex_number = get_dex_number(species_id)
return dex_number > Settings::NB_POKEMON && dex_number < Settings::ZAPMOLCUNO_NB
end
def get_dex_number(species_id)
return GameData::Species.get(species_id).id_number
end
def getBodyID(species, nb_pokemon = Settings::NB_POKEMON)
if species.is_a?(Integer)
dexNum = species
else
dexNum = getDexNumberForSpecies(species)
end
if dexNum % nb_pokemon == 0
return (dexNum / nb_pokemon) - 1
end
return (dexNum / nb_pokemon).round
end
def getHeadID(species, bodyId = nil, nb_pokemon = Settings::NB_POKEMON)
if species.is_a?(Integer)
fused_dexNum = species
else
fused_dexNum = getDexNumberForSpecies(species)
end
if bodyId == nil
bodyId = getBodyID(species)
end
body_dexNum = getDexNumberForSpecies(bodyId)
calculated_number = (fused_dexNum - (body_dexNum * nb_pokemon)).round
return calculated_number == 0 ? nb_pokemon : calculated_number
end
def get_fusion_id(head_number, body_number)
return "B#{body_number}H#{head_number}".to_sym
end
def get_body_id_from_symbol(id)
split_id = id.to_s.match(/\d+/)
if !split_id #non-fusion
return GameData::Species.get(id).id_number
end
return split_id[0].to_i
end
def get_head_id_from_symbol(id)
split_id = id.to_s.match(/(?<=H)\d+/)
if !split_id #non-fusion
return GameData::Species.get(id).id_number
end
return split_id[0].to_i
end
def obtainPokemonSpritePath(id, includeCustoms = true)
head = getBasePokemonID(param.to_i, false)
body = getBasePokemonID(param.to_i, true)
return obtainPokemonSpritePath(body, head, includeCustoms)
end
def obtainPokemonSpritePath(bodyId, headId, include_customs = true)
#download_pokemon_sprite_if_missing(bodyId, headId)
picturePath = _INTL("Graphics/Battlers/{1}/{1}.{2}.png", headId, bodyId)
if include_customs && customSpriteExistsBodyHead(bodyId, headId)
pathCustom = getCustomSpritePath(bodyId, headId)
if (pbResolveBitmap(pathCustom))
picturePath = pathCustom
end
end
return picturePath
end
def getCustomSpritePath(body, head)
return _INTL("#{Settings::CUSTOM_BATTLERS_FOLDER_INDEXED}{1}/{1}.{2}.png", head, body)
end
def customSpriteExistsForm(species, form_id_head = nil, form_id_body = nil)
head = getBasePokemonID(species, false)
body = getBasePokemonID(species, true)
folder = head.to_s
folder += "_" + form_id_head.to_s if form_id_head
spritename = head.to_s
spritename += "_" + form_id_head.to_s if form_id_head
spritename += "." + body.to_s
spritename += "_" + form_id_body.to_s if form_id_body
pathCustom = _INTL("Graphics/.CustomBattlers/indexed/{1}/{2}.png", folder, spritename)
return true if pbResolveBitmap(pathCustom) != nil
return download_custom_sprite(head, body) != nil
end
def get_fusion_spritename(head_id, body_id, alt_letter = "")
return "#{head_id}.#{body_id}#{alt_letter}"
end
def customSpriteExistsSpecies(species)
head = getBasePokemonID(species, false)
body = getBasePokemonID(species, true)
return customSpriteExists(body, head)
# pathCustom = getCustomSpritePath(body, head)
#
# return true if pbResolveBitmap(pathCustom) != nil
# return download_custom_sprite(head, body) != nil
end
def getRandomCustomFusion(returnRandomPokemonIfNoneFound = true, customPokeList = [], maxPoke = -1, recursionLimit = 3)
if customPokeList.length == 0
customPokeList = getCustomSpeciesList(false)
end
randPoke = []
if customPokeList.length >= 5000
chosen = false
i = 0 #loop pas plus que 3 fois pour pas lag
while chosen == false
fusedPoke = customPokeList[rand(customPokeList.length)]
poke1 = getBasePokemonID(fusedPoke, false)
poke2 = getBasePokemonID(fusedPoke, true)
if ((poke1 <= maxPoke && poke2 <= maxPoke) || i >= recursionLimit) || maxPoke == -1
randPoke << getBasePokemonID(fusedPoke, false)
randPoke << getBasePokemonID(fusedPoke, true)
chosen = true
end
end
else
if returnRandomPokemonIfNoneFound
randPoke << rand(maxPoke) + 1
randPoke << rand(maxPoke) + 1
end
end
return randPoke
end
def checkIfCustomSpriteExistsByPath(path)
return true if pbResolveBitmap(path) != nil
end
def customSpriteExistsBodyHead(body, head)
pathCustom = getCustomSpritePath(body, head)
return true if pbResolveBitmap(pathCustom) != nil
return download_custom_sprite(head, body) != nil
end
def customSpriteExistsSpecies(species)
body_id = getBodyID(species)
head_id = getHeadID(species, body_id)
fusion_id = get_fusion_symbol(head_id, body_id)
return $game_temp.custom_sprites_list.include?(fusion_id)
end
def customSpriteExists(body, head)
fusion_id = get_fusion_symbol(head, body)
return $game_temp.custom_sprites_list.include?(fusion_id)
end
#shortcut for using in game events because of script characters limit
def dexNum(species)
return getDexNumberForSpecies(species)
end
def isTripleFusion?(num)
return num >= Settings::ZAPMOLCUNO_NB
end
def isFusion(num)
return num > Settings::NB_POKEMON && !isTripleFusion?(num)
end
def isSpeciesFusion(species)
num = getDexNumberForSpecies(species)
return isFusion(num)
end
def getRandomLocalFusion()
spritesList = []
$PokemonGlobal.alt_sprite_substitutions.each_value do |value|
if value.is_a?(PIFSprite)
spritesList << value
end
end
return spritesList.sample
end
def getRandomFusionForIntro()
random_pokemon = $game_temp.custom_sprites_list.keys.sample || :PIKACHU
alt_letter = $game_temp.custom_sprites_list[random_pokemon]
body_id = get_body_number_from_symbol(random_pokemon)
head_id = get_head_number_from_symbol(random_pokemon)
return PIFSprite.new(:CUSTOM, head_id, body_id, alt_letter)
end
def getSpeciesIdForFusion(head_number, body_number)
return (body_number) * Settings::NB_POKEMON + head_number
end
def get_body_species_from_symbol(fused_id)
body_num = get_body_number_from_symbol(fused_id)
return GameData::Species.get(body_num).species
end
def get_head_species_from_symbol(fused_id)
head_num = get_head_number_from_symbol(fused_id)
return GameData::Species.get(head_num).species
end
def get_body_number_from_symbol(id)
dexNum = getDexNumberForSpecies(id)
return dexNum if !isFusion(dexNum)
id.to_s.match(/\d+/)[0]
return id.to_s.match(/\d+/)[0].to_i
end
def get_head_number_from_symbol(id)
dexNum = getDexNumberForSpecies(id)
return dexNum if !isFusion(dexNum)
return id.to_s.match(/(?<=H)\d+/)[0].to_i
end
def get_fusion_symbol(head_id, body_id)
return "B#{body_id}H#{head_id}".to_sym
end
def getFusionSpecies(body, head)
body_num = getDexNumberForSpecies(body)
head_num = getDexNumberForSpecies(head)
id = body_num * Settings::NB_POKEMON + head_num
return GameData::Species.get(id)
end
def getDexNumberForSpecies(species)
return species if species.is_a?(Integer)
if species.is_a?(Symbol)
dexNum = GameData::Species.get(species).id_number
elsif species.is_a?(Pokemon)
dexNum = GameData::Species.get(species.species).id_number
elsif species.is_a?(GameData::Species)
return species.id_number
else
dexNum = species
end
return dexNum
end
def getFusedPokemonIdFromDexNum(body_dex, head_dex)
return ("B" + body_dex.to_s + "H" + head_dex.to_s).to_sym
end
def getFusedPokemonIdFromSymbols(body_dex, head_dex)
bodyDexNum = GameData::Species.get(body_dex).id_number
headDexNum = GameData::Species.get(head_dex).id_number
return getFusedPokemonIdFromDexNum(bodyDexNum, headDexNum)
end
def generateFusionIcon(dexNum, path)
begin
IO.copy_stream(dexNum, path)
return true
rescue
return false
end
end
def ensureFusionIconExists
directory_name = "Graphics/Pokemon/FusionIcons"
Dir.mkdir(directory_name) unless File.exists?(directory_name)
end
def addNewTripleFusion(pokemon1, pokemon2, pokemon3, level = 1)
return if !pokemon1
return if !pokemon2
return if !pokemon3
if pbBoxesFull?
pbMessage(_INTL("There's no more room for Pokémon!\1"))
pbMessage(_INTL("The Pokémon Boxes are full and can't accept any more!"))
return false
end
pokemon = TripleFusion.new(pokemon1, pokemon2, pokemon3, level)
pokemon.calc_stats
pbMessage(_INTL("{1} obtained {2}!\\me[Pkmn get]\\wtnp[80]\1", $player.name, pokemon.name))
pbNicknameAndStore(pokemon)
#$player.pokedex.register(pokemon)
return true
end
def get_triple_fusion_components(species_id)
dex_num = GameData::Species.get(species_id).id_number
case dex_num
when Settings::ZAPMOLCUNO_NB
return [144,145,146]
when Settings::ZAPMOLCUNO_NB + 1
return [144,145,146]
when Settings::ZAPMOLCUNO_NB + 2
return [243,244,245]
when Settings::ZAPMOLCUNO_NB + 3
return [340,341,342]
when Settings::ZAPMOLCUNO_NB + 4
return [343,344,345]
when Settings::ZAPMOLCUNO_NB + 5
return [349,350,351]
when Settings::ZAPMOLCUNO_NB + 6
return [151,251,381]
when Settings::ZAPMOLCUNO_NB + 11
return [150,348,380]
#starters
when Settings::ZAPMOLCUNO_NB + 7
return [3,6,9]
when Settings::ZAPMOLCUNO_NB + 8
return [154,157,160]
when Settings::ZAPMOLCUNO_NB + 9
return [278,281,284]
when Settings::ZAPMOLCUNO_NB + 10
return [318,321,324]
#starters prevos
when Settings::ZAPMOLCUNO_NB + 12
return [1,4,7]
when Settings::ZAPMOLCUNO_NB + 13
return [2,5,8]
when Settings::ZAPMOLCUNO_NB + 14
return [152,155,158]
when Settings::ZAPMOLCUNO_NB + 15
return [153,156,159]
when Settings::ZAPMOLCUNO_NB + 16
return [276,279,282]
when Settings::ZAPMOLCUNO_NB + 17
return [277,280,283]
when Settings::ZAPMOLCUNO_NB + 18
return [316,319,322]
when Settings::ZAPMOLCUNO_NB + 19
return [317,320,323]
when Settings::ZAPMOLCUNO_NB + 20 #birdBoss Left
return []
when Settings::ZAPMOLCUNO_NB + 21 #birdBoss middle
return [144,145,146]
when Settings::ZAPMOLCUNO_NB + 22 #birdBoss right
return []
when Settings::ZAPMOLCUNO_NB + 23 #sinnohboss left
return []
when Settings::ZAPMOLCUNO_NB + 24 #sinnohboss middle
return [343,344,345]
when Settings::ZAPMOLCUNO_NB + 25 #sinnohboss right
return []
when Settings::ZAPMOLCUNO_NB + 25 #cardboard
return []
when Settings::ZAPMOLCUNO_NB + 26 #cardboard
return []
when Settings::ZAPMOLCUNO_NB + 27 #Triple regi
return [447,448,449]
#Triple Kalos 1
when Settings::ZAPMOLCUNO_NB + 28
return [479,482,485]
when Settings::ZAPMOLCUNO_NB + 29
return [480,483,486]
when Settings::ZAPMOLCUNO_NB + 30
return [481,484,487]
else
return [000]
end
end
def reverseFusionSpecies(species)
dexId = getDexNumberForSpecies(species)
return species if dexId <= NB_POKEMON
return species if dexId > (NB_POKEMON * NB_POKEMON) + NB_POKEMON
body = getBasePokemonID(dexId, true)
head = getBasePokemonID(dexId, false)
newspecies = (head) * NB_POKEMON + body
return getPokemon(newspecies)
end

View File

@@ -0,0 +1,29 @@
# frozen_string_literal: true
def pokemart_clothes_shop(current_city = nil, include_defaults = true)
current_city = pbGet(VAR_CURRENT_MART) if !current_city
echoln current_city
current_city = :PEWTER if !current_city.is_a?(Symbol)
current_city_tag = current_city.to_s.downcase
selector = OutfitSelector.new
list = selector.generate_clothes_choice(
baseOptions = include_defaults,
additionalIds = [],
additionalTags = [current_city_tag],
filterOutTags = [])
clothesShop(list)
end
def pokemart_hat_shop(include_defaults = true)
current_city = pbGet(VAR_CURRENT_MART)
current_city = :PEWTER if !current_city.is_a?(Symbol)
current_city_tag = current_city.to_s.downcase
selector = OutfitSelector.new
list = selector.generate_hats_choice(
baseOptions = include_defaults,
additionalIds = [],
additionalTags = [current_city_tag],
filterOutTags = [])
hatShop(list)
end

View File

@@ -0,0 +1,53 @@
def get_mart_exclusive_items(city)
items_list = []
case city
when :PEWTER;
items_list = [:ROCKGEM, :NESTBALL]
when :VIRIDIAN;
items_list = []
when :CERULEAN;
items_list = [:WATERGEM, :NETBALL, :PRETTYWING]
when :VERMILLION;
items_list = [:LOVEBALL, :ELECTRICGEM]
when :LAVENDER;
items_list = [:GHOSTGEM, :DARKGEM, :DUSKBALL]
when :CELADON;
items_list = [:GRASSGEM, :FLYINGGEM, :QUICKBALL, :TIMERBALL,]
when :FUCHSIA;
items_list = [:POISONGEM, :REPEATBALL]
when :SAFFRON;
items_list = [:PSYCHICGEM, :FIGHTINGGEM, :FRIENDBALL]
when :CINNABAR;
items_list = [:FIREGEM, :ICEGEM, :HEAVYBALL]
when :CRIMSON;
items_list = [:DRAGONGEM, :LEVELBALL]
when :GOLDENROD;
items_list = [:EVERSTONE, :MOONSTONE, :SUNSTONE, :DUSKSTONE, :DAWNSTONE, :SHINYSTONE]
when :AZALEA;
items_list = [:BUGGEM]
when :VIOLET;
items_list = [:FLYINGGEM, :STATUSBALL]
when :BLACKTHORN;
items_list = [:DRAGONGEM, :CANDYBALL]
when :CHERRYGROVE;
items_list = [:BUGGEM, :PUREBALL]
when :MAHOGANY;
items_list = []
when :ECRUTEAK;
items_list = [:GHOSTGEM, :DARKGEM]
when :OLIVINE;
items_list = []
when :CIANWOOD;
items_list = []
when :KNOTISLAND;
items_list = []
when :BOONISLAND;
items_list = []
when :KINISLAND;
items_list = []
when :CHRONOISLAND;
items_list = []
end
return items_list
end# frozen_string_literal: true

View File

@@ -0,0 +1,121 @@
# frozen_string_literal: true
module GameData
class TerrainTag
attr_reader :flowerRed
attr_reader :flowerPink
attr_reader :flowerYellow
attr_reader :flowerBlue
attr_reader :flower
attr_reader :trashcan
attr_reader :sharpedoObstacle
alias original_TerrainTag_init initialize
def initialize(hash)
original_TerrainTag_init(hash)
@waterCurrent = hash[:waterCurrent] || false
@flowerRed = hash[:flowerRed] || false
@flowerYellow = hash[:flowerYellow] || false
@flowerPink = hash[:flowerPink] || false
@flowerBlue = hash[:flowerBlue] || false
@flower = hash[:flower] || false
@trashcan = hash[:trashcan] || false
@sharpedoObstacle = hash[:sharpedoObstacle] || false
end
end
end
GameData::TerrainTag.register({
:id => :WaterCurrent,
:id_number => 6,
:can_surf => true,
:can_fish => true,
:waterCurrent => true,
:battle_environment => :MovingWater
})
GameData::TerrainTag.register({
:id => :FlowerRed,
:id_number => 17,
:flowerRed => true,
:flower => true
})
GameData::TerrainTag.register({
:id => :FlowerYellow,
:id_number => 18,
:flowerYellow => true,
:flower => true
})
GameData::TerrainTag.register({
:id => :FlowerPink,
:id_number => 19,
:flowerPink => true,
:flower => true
})
GameData::TerrainTag.register({
:id => :FlowerBlue,
:id_number => 20,
:flowerBlue => true,
:flower => true
})
GameData::TerrainTag.register({
:id => :FlowerOther,
:id_number => 21,
:flower => true
})
GameData::TerrainTag.register({
:id => :Trashcan,
:id_number => 22,
:trashcan => true
})
GameData::TerrainTag.register({
:id => :SharpedoObstacle,
:id_number => 23,
:sharpedoObstacle => true
})
GameData::TerrainTag.register({
:id => :Grass_alt1,
:id_number => 24,
:shows_grass_rustle => true,
:land_wild_encounters => true,
:battle_environment => :Grass
})
GameData::TerrainTag.register({
:id => :Grass_alt2,
:id_number => 25,
:shows_grass_rustle => true,
:land_wild_encounters => true,
:battle_environment => :Grass
})
GameData::TerrainTag.register({
:id => :Grass_alt3,
:id_number => 26,
:shows_grass_rustle => true,
:land_wild_encounters => true,
:battle_environment => :Grass
})
GameData::TerrainTag.register({
:id => :StillWater,
:id_number => 27,
:can_surf => true,
:can_fish => true,
:battle_environment => :StillWater,
:shows_reflections => true
})
GameData::TerrainTag.register({
:id => :NoEffect,
:id_number => 99
})

View File

@@ -0,0 +1,38 @@
def turnEventTowardsEvent(turning, turnedTowards)
event_x = turnedTowards.x
event_y = turnedTowards.y
if turning.x < event_x
turning.turn_right # Event is to the right of the player
elsif turning.x > event_x
turning.turn_left # Event is to the left of the player
elsif turning.y < event_y
turning.turn_down # Event is below the player
elsif turning.y > event_y
turning.turn_up # Event is above the player
end
end
def turnPlayerTowardsEvent(event)
event_x = event.x
event_y = event.y
if $game_player.x < event_x
$game_player.turn_right # Event is to the right of the player
elsif $game_player.x > event_x
$game_player.turn_left # Event is to the left of the player
elsif $game_player.y < event_y
$game_player.turn_down # Event is below the player
elsif $game_player.y > event_y
$game_player.turn_up # Event is above the player
end
end
def player_near_event?(map_id, event_id, radius)
return false if map_id != $game_map.map_id
event = $game_map.events[event_id]
return false if event.nil?
dx = $game_player.x - event.x
dy = $game_player.y - event.y
distance = Math.sqrt(dx * dx + dy * dy)
return distance <= radius
end

View File

@@ -0,0 +1,6 @@
def has_species_or_fusion?(species, form = -1)
return $player.pokemon_party.any? { |p| p && p.isSpecies?(species) || p.isFusionOf(species) }
end
# frozen_string_literal: true

View File

@@ -0,0 +1,589 @@
def getAllCurrentlyRoamingPokemon
currently_roaming = []
Settings::ROAMING_SPECIES.each_with_index do |data, i|
next if !GameData::Species.exists?(data[0])
next if data[2] > 0 && !$game_switches[data[2]] # Isn't roaming
next if $PokemonGlobal.roamPokemon[i] == true # Roaming Pokémon has been caught
currently_roaming << i
end
return currently_roaming
end
def track_pokemon()
currently_roaming = getAllCurrentlyRoamingPokemon()
echoln currently_roaming
weather_data = []
mapinfos = $RPGVX ? load_data("Data/MapInfos.rvdata") : load_data("Data/MapInfos.rxdata")
currently_roaming.each do |roamer_id|
map_id = $PokemonGlobal.roamPosition[roamer_id]
map_name = mapinfos[map_id].name
weather_type = Settings::ROAMING_SPECIES[roamer_id][6]
case weather_type
when :Storm
forecast_msg = _INTL("An unusual \\c[6]thunderstorm\\c[0] has been detected around \\c[6]{1}", map_name)
when :StrongWinds
forecast_msg = _INTL("Unusually \\c[9]strong winds\\c[0] have been detected around \\c[9]{1}", map_name)
when :Sunny
forecast_msg = _INTL("Unusually \\c[10]harsh sunlight\\c[0] has been detected around \\c[10]{1}", map_name)
end
weather_data << forecast_msg if forecast_msg && !weather_data.include?(forecast_msg)
end
weather_data << _INTL("No unusual weather patterns have been detected.") if weather_data.empty?
weather_data.each do |message|
Kernel.pbMessage(message)
end
end
# frozen_string_literal: true
def getHiddenPowerName(pokemon)
hiddenpower = pbHiddenPower(pokemon)
hiddenPowerType = hiddenpower[0]
echoln hiddenPowerType
if Settings::TRIPLE_TYPES.include?(hiddenPowerType)
return "Neutral"
end
return PBTypes.getName(hiddenPowerType)
end
# Returns if the current map is an outdoor map
def isOutdoor()
current_map = $game_map.map_id
map_metadata = GameData::MapMetadata.try_get(current_map)
return map_metadata && map_metadata.outdoor_map
end
def qmarkMaskCheck()
if $player.seen_qmarks_sprite
unless hasHat?(HAT_QMARKS)
obtainHat(HAT_QMARKS)
obtainClothes(CLOTHES_GLITCH)
end
end
end
def giveJigglypuffScribbles(possible_versions = [1,2,3,4])
selected_scribbles_version = possible_versions.sample
case selected_scribbles_version
when 1
scribbles_id= HAT_SCRIBBLES1
when 2
scribbles_id= HAT_SCRIBBLES2
when 3
scribbles_id= HAT_SCRIBBLES3
when 4
scribbles_id= HAT_SCRIBBLES4
end
return if !scribbles_id
if !hasHat?(scribbles_id)
$player.unlocked_hats << scribbles_id
end
putOnHat(scribbles_id,true,true)
end
# chance: out of 100
def lilypadEncounter(pokemon, minLevel, maxLevel, chance = 10)
minLevel, maxLevel = [minLevel, maxLevel].minmax
level = rand(minLevel..maxLevel)
event = $game_map.events[@event_id]
return if !event
if rand(0..100) <= chance
pbWildBattle(pokemon, level)
else
playAnimation(Settings::GRASS_ANIMATION_ID, event.x, event.y)
end
event.erase
end
def calculate_pokemon_weight(pokemon, nerf = 0)
base_weight = pokemon.weight
ivs = []
pokemon.iv.each { |iv|
ivs << iv[1]
}
level = pokemon.level
# Ensure IVs is an array of 6 values and level is between 1 and 100
raise "IVs array must have 6 values" if ivs.length != 6
raise "Level must be between 1 and 100" unless (1..100).include?(level)
# Calculate the IV Factor
iv_sum = ivs.sum
iv_factor = (iv_sum.to_f / 186) * 30 * 10
# Calculate the Level Factor
level_factor = (level.to_f / 100) * 5 * 10
# Calculate the weight
weight = base_weight * (1 + (iv_factor / 100) + (level_factor / 100))
weight -= base_weight
# Enforce the weight variation limits
max_weight = base_weight * 4.00 # 400% increase
min_weight = base_weight * 0.5 # 50% decrease
# Cap the weight between min and max values
weight = [[weight, min_weight].max, max_weight].min
weight -= nerf if weight - nerf > min_weight
return weight.round(2) # Round to 2 decimal places
end
# nerf: remove x kg from each generated pokemon
def generate_weight_contest_entries(species, level, resultsVariable, nerf = 0)
# echoln "Generating Pokemon"
pokemon1 = pbGenerateWildPokemon(species, level) # Pokemon.new(species,level)
pokemon2 = pbGenerateWildPokemon(species, level) # Pokemon.new(species,level)
new_weights = []
new_weights << calculate_pokemon_weight(pokemon1, nerf)
new_weights << calculate_pokemon_weight(pokemon2, nerf)
echoln new_weights
echoln "(nerfed by -#{nerf})"
pbSet(resultsVariable, new_weights.max)
end
# time in seconds
def idleHatEvent(hatId, time, switchToActivate = nil)
map = $game_map.map_id
i = 0
while i < (time / 5) do
# /5 because we update 5 times per second
return if $game_map.map_id != map
i += 1
pbWait(4)
i = 0 if $game_player.moving?
echoln i
end
$game_switches[switchToActivate] = true if switchToActivate
obtainHat(hatId)
end
def obtainStarter(starterIndex = 0)
if ($game_switches[SWITCH_RANDOM_STARTERS])
starter = obtainRandomizedStarter(starterIndex)
else
startersList = Settings::KANTO_STARTERS
if $game_switches[SWITCH_JOHTO_STARTERS]
startersList = Settings::JOHTO_STARTERS
elsif $game_switches[SWITCH_HOENN_STARTERS]
startersList = Settings::HOENN_STARTERS
elsif $game_switches[SWITCH_SINNOH_STARTERS]
startersList = Settings::SINNOH_STARTERS
elsif $game_switches[SWITCH_KALOS_STARTERS]
startersList = Settings::KALOS_STARTERS
end
starter = startersList[starterIndex]
end
return GameData::Species.get(starter)
end
def isPostgame?()
return $game_switches[SWITCH_BEAT_THE_LEAGUE]
end
def constellation_add_star(pokemon)
star_variables = get_constellation_variable(pokemon)
pbSEPlay("GUI trainer card open", 80)
nb_stars = pbGet(star_variables)
pbSet(star_variables, nb_stars + 1)
end
def get_constellation_variable(pokemon)
case pokemon
when :IVYSAUR;
return VAR_CONSTELLATION_IVYSAUR
when :WARTORTLE;
return VAR_CONSTELLATION_WARTORTLE
when :ARCANINE;
return VAR_CONSTELLATION_ARCANINE
when :MACHOKE;
return VAR_CONSTELLATION_MACHOKE
when :RAPIDASH;
return VAR_CONSTELLATION_RAPIDASH
when :GYARADOS;
return VAR_CONSTELLATION_GYARADOS
when :ARTICUNO;
return VAR_CONSTELLATION_ARTICUNO
when :MEW;
return VAR_CONSTELLATION_MEW
# when :POLITOED; return VAR_CONSTELLATION_POLITOED
# when :URSARING; return VAR_CONSTELLATION_URSARING
# when :LUGIA; return VAR_CONSTELLATION_LUGIA
# when :HOOH; return VAR_CONSTELLATION_HOOH
# when :CELEBI; return VAR_CONSTELLATION_CELEBI
# when :SLAKING; return VAR_CONSTELLATION_SLAKING
# when :JIRACHI; return VAR_CONSTELLATION_JIRACHI
# when :TYRANTRUM; return VAR_CONSTELLATION_TYRANTRUM
# when :SHARPEDO; return VAR_CONSTELLATION_SHARPEDO
# when :ARCEUS; return VAR_CONSTELLATION_ARCEUS
end
end
def getNextLunarFeatherHint()
nb_feathers = pbGet(VAR_LUNAR_FEATHERS)
case nb_feathers
when 0
return "Find the first feather in the northernmost dwelling in the port of exquisite sunsets..."
when 1
return "Amidst a nursery for Pokémon youngsters, the second feather hides, surrounded by innocence."
when 2
return "Find the next one in the inn where water meets rest"
when 3
return "Find the next one inside the lone house in the city at the edge of civilization."
when 4
return "The final feather lies back in the refuge for orphaned Pokémon..."
else
return "Lie in the bed... Bring me the feathers..."
end
end
def apply_concert_lighting(light, duration = 1)
tone = Tone.new(0, 0, 0)
case light
when :GUITAR_HIT
tone = Tone.new(-50, -100, -50)
when :VERSE_1
tone = Tone.new(-90, -110, -50)
when :VERSE_2_LIGHT
tone = Tone.new(-40, -80, -30)
when :VERSE_2_DIM
tone = Tone.new(-60, -100, -50)
when :CHORUS_1
tone = Tone.new(0, -80, -50)
when :CHORUS_2
tone = Tone.new(0, -50, -80)
when :CHORUS_3
tone = Tone.new(0, -80, -80)
when :CHORUS_END
tone = Tone.new(-68, 0, -102)
when :MELOETTA_1
tone = Tone.new(-60, -50, 20)
end
$game_screen.start_tone_change(tone, duration)
end
def playMeloettaBandMusic()
unlocked_members = []
unlocked_members << :DRUM if $game_switches[SWITCH_BAND_DRUMMER]
unlocked_members << :AGUITAR if $game_switches[SWITCH_BAND_ACOUSTIC_GUITAR]
unlocked_members << :EGUITAR if $game_switches[SWITCH_BAND_ELECTRIC_GUITAR]
unlocked_members << :FLUTE if $game_switches[SWITCH_BAND_FLUTE]
unlocked_members << :HARP if $game_switches[SWITCH_BAND_HARP]
echoln unlocked_members
echoln (unlocked_members & [:DRUM, :AGUITAR, :EGUITAR, :FLUTE, :HARP])
track = "band/band_1"
if unlocked_members == [:DRUM, :AGUITAR, :EGUITAR, :FLUTE, :HARP]
track = "band/band_full"
else
if unlocked_members.include?(:FLUTE)
track = "band/band_5a"
elsif unlocked_members.include?(:HARP)
track = "band/band_5b"
else
if unlocked_members.include?(:EGUITAR) && unlocked_members.include?(:AGUITAR)
track = "band/band_4"
elsif unlocked_members.include?(:AGUITAR)
track = "band/band_3a"
elsif unlocked_members.include?(:EGUITAR)
track = "band/band_3b"
elsif unlocked_members.include?(:DRUM)
track = "band/band_2"
end
end
end
echoln track
pbBGMPlay(track)
end
def regirock_steel_move_boulder()
switches_position = [
[16, 21], [18, 21], [20, 21], [22, 21],
[16, 23], [22, 23],
[16, 25], [18, 25], [20, 25], [22, 25]
]
boulder_event = get_self
old_x = boulder_event.x
old_y = boulder_event.y
stepped_off_switch = switches_position.find { |position| position[0] == old_x && position[1] == old_y }
pbPushThisBoulder()
boulder_event = get_self
if stepped_off_switch
switch_event = $game_map.get_event_at_position(old_x, old_y, [boulder_event.id])
echoln switch_event.id if switch_event
pbSEPlay("Entering Door", nil, 80)
pbSetSelfSwitch(switch_event.id, "A", false) if switch_event
end
stepped_on_switch = switches_position.find { |position| position[0] == boulder_event.x && position[1] == boulder_event.y }
if stepped_on_switch
switch_event = $game_map.get_event_at_position(boulder_event.x, boulder_event.y, [boulder_event.id])
echoln switch_event.id if switch_event
pbSEPlay("Entering Door")
pbSetSelfSwitch(switch_event.id, "A", true) if switch_event
end
end
KANTO_DARKNESS_STAGE_1 = [
50, # Lavender town
409, # Route 8
351, # Route 9 (east)
495, # Route 9 (west)
154, # Route 10
108, # Saffron city
1, # Cerulean City
387, # Cerulean City (race)
106, # Route 4
8, # Route 24
9, # Route 25
400, # Pokemon Tower
401, # Pokemon Tower
402, # Pokemon Tower
403, # Pokemon Tower
467, # Pokemon Tower
468, # Pokemon Tower
469, # Pokemon Tower
159, # Route 12
349, # Rock tunnel
350, # Rock tunnel
512, # Rock tunnel (outdoor)
12, # Route 5
]
KANTO_DARKNESS_STAGE_2 = [
95, # Celadon city
436, # Celadon city dept store (roof)
143, # Route 23
167, # Crimson city
413, # Route 7
438, # Route 16
146, # Route 17
106, # Route 4
19, # Vermillion City
36, # S.S. Anne deck
16, # Route 6
437, # Route 13
155, # Route 11
140, # Diglett cave
398, # Diglett cave
399, # Diglett cave
]
KANTO_DARKNESS_STAGE_3 = [
472, # Fuchsia city
445, # Safari Zone 1
484, # Safari Zone 2
485, # Safari Zone 3
486, # Safari Zone 4
487, # Safari Zone 5
444, # Route 15
440, # Route 14
712, # Creepy house
517, # Route 18
57, # Route 19
227, # Route 19 (underwater)
56, # Route 19 (surf race)
58, # Route 20
480, # Route 20 underwater 1
228, # Route 20 underwater 2
98, # Cinnabar island
58, # Route 21
827, # Mt. Moon summit
]
KANTO_DARKNESS_STAGE_4 = KANTO_OUTDOOR_MAPS
def darknessEffectOnCurrentMap()
return if !$game_switches
return if !$game_switches[SWITCH_KANTO_DARKNESS]
return darknessEffectOnMap($game_map.map_id)
end
def darknessEffectOnMap(map_id)
return if !$game_switches
return if !$game_switches[SWITCH_KANTO_DARKNESS]
return if !KANTO_OUTDOOR_MAPS.include?(map_id)
dark_maps = []
dark_maps += KANTO_DARKNESS_STAGE_1 if $game_switches[SWITCH_KANTO_DARKNESS_STAGE_1]
dark_maps += KANTO_DARKNESS_STAGE_2 if $game_switches[SWITCH_KANTO_DARKNESS_STAGE_2]
dark_maps += KANTO_DARKNESS_STAGE_3 if $game_switches[SWITCH_KANTO_DARKNESS_STAGE_3]
dark_maps = KANTO_OUTDOOR_MAPS if $game_switches[SWITCH_KANTO_DARKNESS_STAGE_4]
return dark_maps.include?(map_id)
end
def apply_darkness()
$PokemonTemp.darknessSprite = DarknessSprite.new
darkness = $PokemonTemp.darknessSprite
darkness.radius = 276
while darkness.radius > 64
Graphics.update
Input.update
pbUpdateSceneMap
darkness.radius -= 4
end
$PokemonGlobal.flashUsed = false
$PokemonTemp.darknessSprite.dispose
Events.onMapSceneChange.trigger(self, $scene, true)
end
def isInMtMoon()
mt_moon_maps = [102, 103, 105, 496, 104]
return mt_moon_maps.include?($game_map.map_id)
end
def getMtMoonDirection()
maps_east = [380, # Pewter city
490, # Route 3
303, # indigo plateau
145, # Route 26
147, # Route 27
]
maps_south = [
8, # Route 24
9, # Route 25
143, # Route 23
167, # Crimson city
]
maps_west = [
106, # route 4
1, # cerulean
495, # route 9
351, # route 9
10 # cerulean cape
]
return 2 if maps_south.include?($game_map.map_id)
return 4 if maps_west.include?($game_map.map_id)
return 6 if maps_east.include?($game_map.map_id)
return 8 # north (most maps)
end
def Kernel.setRocketPassword(variableNum)
abilityIndex = rand(233)
speciesIndex = rand(PBSpecies.maxValue - 1)
word1 = PBSpecies.getName(speciesIndex)
word2 = GameData::Ability.get(abilityIndex).name
password = _INTL("{1}'s {2}", word1, word2)
pbSet(variableNum, password)
end
def obtainBadgeMessage(badgeName)
Kernel.pbMessage(_INTL("\\me[Badge get]{1} obtained the {2}!", $player.name, badgeName))
end
def getFossilsGuyTeam(level)
base_poke_evolution_level = 20
fossils_evolution_level_1 = 30
fossils_evolution_level_2 = 50
fossils = []
base_poke = level <= base_poke_evolution_level ? :B88H109 : :B89H110
team = []
team << Pokemon.new(base_poke, level)
# Mt. Moon fossil
if $game_switches[SWITCH_PICKED_HELIC_FOSSIL]
fossils << :KABUTO if level < fossils_evolution_level_1
fossils << :KABUTOPS if level >= fossils_evolution_level_1
elsif $game_switches[SWITCH_PICKED_DOME_FOSSIL]
fossils << :OMANYTE if level < fossils_evolution_level_1
fossils << :OMASTAR if level >= fossils_evolution_level_1
end
# S.S. Anne fossil
if $game_switches[SWITCH_PICKED_LILEEP_FOSSIL]
fossils << :ANORITH if level < fossils_evolution_level_1
fossils << :ARMALDO if level >= fossils_evolution_level_1
elsif $game_switches[SWITCH_PICKED_ANORITH_FOSSIL]
fossils << :LILEEP if level < fossils_evolution_level_1
fossils << :CRADILY if level >= fossils_evolution_level_1
end
# Celadon fossil
if $game_switches[SWITCH_PICKED_ARMOR_FOSSIL]
fossils << :CRANIDOS if level < fossils_evolution_level_2
fossils << :RAMPARDOS if level >= fossils_evolution_level_2
elsif $game_switches[SWITCH_PICKED_SKULL_FOSSIL]
fossils << :SHIELDON if level < fossils_evolution_level_2
fossils << :BASTIODON if level >= fossils_evolution_level_2
end
skip_next = false
for index in 0..fossils.length
if index == fossils.length - 1
team << Pokemon.new(fossils[index], level)
else
if skip_next
skip_next = false
next
end
head_poke = fossils[index]
body_poke = fossils[index + 1]
if head_poke && body_poke
newPoke = getFusionSpecies(dexNum(body_poke), dexNum(head_poke))
team << Pokemon.new(newPoke, level)
skip_next = true
end
end
end
return team
end
# tradedPoke = pbGet(154)
# party=[tradedPoke]
# customTrainerBattle("Eusine",
# :MYSTICALMAN,
# party,
# tradedPoke.level,
# "Okay, okay I'll give it back!" )
def fossilsGuyBattle(level = 20, end_message = "")
team = getFossilsGuyTeam(level)
customTrainerBattle("Miguel",
:SUPERNERD,
team,
level,
end_message
)
end
def isOnPinkanIsland()
return false
end
def generateSimpleTrainerParty(teamSpecies, level)
team = []
for species in teamSpecies
poke = Pokemon.new(species, level)
team << poke
end
return team
end
def generateEggGroupTeam(eggGroup)
teamComplete = false
generatedTeam = []
while !teamComplete
species = rand(PBSpecies.maxValue)
if getPokemonEggGroups(species).include?(eggGroup)
generatedTeam << species
end
teamComplete = generatedTeam.length == 3
end
return generatedTeam
end

View File

@@ -0,0 +1,103 @@
# frozen_string_literal: true
def addWaterCausticsEffect(fog_name = "caustic1", opacity = 16)
$game_map.fog_name = fog_name
$game_map.fog_hue = 0
$game_map.fog_opacity = opacity
#$game_map.fog_blend_type = @parameters[4]
$game_map.fog_zoom = 200
$game_map.fog_sx = 2
$game_map.fog_sy = 2
$game_map.setFog2(fog_name, -3, 0, opacity,)
end
def stopWaterCausticsEffect()
$game_map.fog_opacity = 0
$game_map.eraseFog2()
end
def clear_all_images()
for i in 1..99
# echoln i.to_s + " : " + $game_screen.pictures[i].name
$game_screen.pictures[i].erase
end
end
def playPokeFluteAnimation
# return if $player.outfit != 0
# $game_player.setDefaultCharName("players/pokeflute", 0, false)
# Graphics.update
# Input.update
# pbUpdateSceneMap
end
def restoreDefaultCharacterSprite(charset_number = 0)
meta = GameData::Metadata.get_player($player.character_ID)
$game_player.setDefaultCharName(nil, 0, false)
$game_player.character_name = meta[1]
Graphics.update
Input.update
pbUpdateSceneMap
end
# if need to play animation from event route
def playAnimation(animationId, x, y)
return if !$scene.is_a?(Scene_Map)
$scene.spriteset.addUserAnimation(animationId, x, y, true)
end
def get_spritecharacter_for_event(event_id)
for sprite in $scene.spriteset.character_sprites
if sprite.character.id == event_id
return sprite
end
end
end
def pbBitmap(path)
if !pbResolveBitmap(path).nil?
bmp = RPG::Cache.load_bitmap_path(path)
bmp.storedPath = path
else
p "Image located at '#{path}' was not found!" if $DEBUG
bmp = Bitmap.new(1, 1)
end
return bmp
end
def addShinyStarsToGraphicsArray(imageArray, xPos, yPos, shinyBody, shinyHead, debugShiny, srcx = nil, srcy = nil, width = nil, height = nil,
showSecondStarUnder = false, showSecondStarAbove = false)
color = debugShiny ? Color.new(0, 0, 0, 255) : nil
imageArray.push(["Graphics/Pictures/shiny", xPos, yPos, srcx, srcy, width, height, color])
if shinyBody && shinyHead
if showSecondStarUnder
yPos += 15
elsif showSecondStarAbove
yPos -= 15
else
xPos -= 15
end
imageArray.push(["Graphics/Pictures/shiny", xPos, yPos, srcx, srcy, width, height, color])
end
end
def pbCheckPokemonIconFiles(speciesID, egg = false, dna = false)
if egg
bitmapFileName = sprintf("Graphics/Icons/iconEgg")
return pbResolveBitmap(bitmapFileName)
else
bitmapFileName = _INTL("Graphics/Pokemon/Icons/{1}", speciesID)
ret = pbResolveBitmap(bitmapFileName)
return ret if ret
end
ret = pbResolveBitmap("Graphics/Icons/iconDNA.png")
return ret if ret
return pbResolveBitmap("Graphics/Icons/iconDNA.png")
end
def pbPokemonIconFile(pokemon)
bitmapFileName = pbCheckPokemonIconFiles(pokemon.species, pokemon.isEgg?)
return bitmapFileName
end

View File

@@ -0,0 +1,180 @@
def optionsMenu(options = [], cmdIfCancel = -1, startingOption = 0)
cmdIfCancel = -1 if !cmdIfCancel
result = pbShowCommands(nil, options, cmdIfCancel, startingOption)
echoln "menuResult :#{result}"
return result
end
def displaySpriteWindowWithMessage(pif_sprite, message = "", x = 0, y = 0, z = 0)
spriteLoader = BattleSpriteLoader.new
sprite_bitmap = spriteLoader.load_pif_sprite_directly(pif_sprite)
pictureWindow = PictureWindow.new(sprite_bitmap.bitmap)
pictureWindow.opacity = 0
pictureWindow.z = z
pictureWindow.x = x
pictureWindow.y = y
pbMessage(message)
pictureWindow.dispose
end
def select_any_pokemon()
commands = []
for dex_num in 1..NB_POKEMON
species = getPokemon(dex_num)
commands.push([dex_num - 1, species.real_name, species.id])
end
return pbChooseList(commands, 0, nil, 1)
end
def purchaseDyeKitMenu(hats_kit_price=0,clothes_kit_price=0)
commands = []
command_hats = "Hats Dye Kit ($#{hats_kit_price})"
command_clothes = "Clothes Dye Kit ($#{clothes_kit_price})"
command_cancel = "Cancel"
commands << command_hats if !$PokemonBag.pbHasItem?(:HATSDYEKIT)
commands << command_clothes if !$PokemonBag.pbHasItem?(:CLOTHESDYEKIT)
commands << command_cancel
if commands.length <= 1
pbCallBub(2,@event_id)
pbMessage("\\C[1]Dye Kits\\C[0] can be used to dye clothes all sorts of colours!")
pbCallBub(2,@event_id)
pbMessage("You can use them at any time when you change clothes.")
return
end
pbCallBub(2,@event_id)
pbMessage("\\GWelcome! Are you interested in dyeing your outfits different colours?")
pbCallBub(2,@event_id)
pbMessage("I make handy \\C[1]Dye Kits\\C[0] from my Smeargle's paint that can be used to dye your outfits any color you want!")
pbCallBub(2,@event_id)
pbMessage("\\GWhat's more is that it's reusable so you can go completely wild with it if you want! Are you interested?")
choice = optionsMenu(commands,commands.length)
case commands[choice]
when command_hats
if $player.money < hats_kit_price
pbCallBub(2,@event_id)
pbMessage("Oh, you don't have enough money...")
return
end
pbMessage("\\G\\PN purchased the dye kit.")
$player.money -= hats_kit_price
pbSEPlay("SlotsCoin")
Kernel.pbReceiveItem(:HATSDYEKIT)
pbCallBub(2,@event_id)
pbMessage("\\GHere you go! Have fun dyeing your hats!")
when command_clothes
if $player.money < clothes_kit_price
pbCallBub(2,@event_id)
pbMessage("Oh, you don't have enough money...")
return
end
pbMessage("\\G\\PN purchased the dye kit.")
$player.money -= clothes_kit_price
pbSEPlay("SlotsCoin")
Kernel.pbReceiveItem(:CLOTHESDYEKIT)
pbCallBub(2,@event_id)
pbMessage("\\GHere you go! Have fun dyeing your clothes!")
end
pbCallBub(2,@event_id)
pbMessage("You can use \\C[1]Dye Kits\\C[0] at any time when you change clothes.")
end
def promptCaughtPokemonAction(pokemon)
pickedOption = false
return pbStorePokemon(pokemon) if !$player.party_full?
return promptKeepOrRelease(pokemon) if isOnPinkanIsland() && !$game_switches[SWITCH_PINKAN_FINISHED]
while !pickedOption
command = pbMessage(_INTL("\\ts[]Your team is full!"),
[_INTL("Add to your party"), _INTL("Store to PC"),], 2)
echoln ("command " + command.to_s)
case command
when 0 # SWAP
if swapCaughtPokemon(pokemon)
echoln pickedOption
pickedOption = true
end
else
# STORE
pbStorePokemon(pokemon)
echoln pickedOption
pickedOption = true
end
end
end
def promptKeepOrRelease(pokemon)
pickedOption = false
while !pickedOption
command = pbMessage(_INTL("\\ts[]Your team is full!"),
[_INTL("Release a party member"), _INTL("Release this #{pokemon.name}"),], 2)
echoln ("command " + command.to_s)
case command
when 0 # SWAP
if swapReleaseCaughtPokemon(pokemon)
pickedOption = true
end
else
pickedOption = true
end
end
end
# def pbChoosePokemon(variableNumber, nameVarNumber, ableProc = nil, allowIneligible = false)
def swapCaughtPokemon(caughtPokemon)
pbChoosePokemon(1, 2,
proc { |poke|
!poke.egg? &&
!(poke.isShadow? rescue false)
})
index = pbGet(1)
return false if index == -1
$PokemonStorage.pbStoreCaught($player.party[index])
pbRemovePokemonAt(index)
pbStorePokemon(caughtPokemon)
tmp = $player.party[index]
$player.party[index] = $player.party[-1]
$player.party[-1] = tmp
return true
end
def swapReleaseCaughtPokemon(caughtPokemon)
pbChoosePokemon(1, 2,
proc { |poke|
!poke.egg? &&
!(poke.isShadow? rescue false)
})
index = pbGet(1)
return false if index == -1
releasedPokemon = $player.party[index]
pbMessage("#{releasedPokemon.name} was released.")
pbRemovePokemonAt(index)
pbStorePokemon(caughtPokemon)
tmp = $player.party[index]
$player.party[index] = $player.party[-1]
$player.party[-1] = tmp
return true
end
def Kernel.getItemNamesAsString(list)
strList = ""
for i in 0..list.length - 1
id = list[i]
name = PBItems.getName(id)
strList += name
if i != list.length - 1 && list.length > 1
strList += ","
end
end
return strList
end

View File

@@ -0,0 +1,56 @@
# frozen_string_literal: true
def unlock_easter_egg_hats()
if $player.name == "Ash"
$player.hat = HAT_ASH
$player.unlock_hat(HAT_ASH)
end
if $player.name == "Frogman"
$player.hat = HAT_FROG
$player.unlock_hat(HAT_FROG)
end
end
def setupStartingOutfit()
$player.hat = nil
$player.clothes = STARTING_OUTFIT
unlock_easter_egg_hats()
gender = pbGet(VAR_TRAINER_GENDER)
if gender == GENDER_FEMALE
$player.unlock_clothes(DEFAULT_OUTFIT_FEMALE, true)
$player.unlock_hat(DEFAULT_OUTFIT_FEMALE, true)
$player.hair = "3_" + DEFAULT_OUTFIT_FEMALE if !$player.hair # when migrating old savefiles
elsif gender == GENDER_MALE
$player.unlock_clothes(DEFAULT_OUTFIT_MALE, true)
$player.unlock_hat(DEFAULT_OUTFIT_MALE, true)
echoln $player.hair
$player.hair = ("3_" + DEFAULT_OUTFIT_MALE) if !$player.hair # when migrating old savefiles
echoln $player.hair
end
$player.unlock_hair(DEFAULT_OUTFIT_MALE, true)
$player.unlock_hair(DEFAULT_OUTFIT_FEMALE, true)
$player.unlock_clothes(STARTING_OUTFIT, true)
end
def give_date_specific_hats()
current_date = Time.new
# Christmas
if (current_date.day == 24 || current_date.day == 25) && current_date.month == 12
if !$player.unlocked_hats.include?(HAT_SANTA)
pbCallBub(2, @event_id, true)
pbMessage("Hi! We're giving out a special hat today for the holidays season. Enjoy!")
obtainHat(HAT_SANTA)
end
end
# April's fool
if (current_date.day == 1 && current_date.month == 4)
if !$player.unlocked_hats.include?(HAT_CLOWN)
pbCallBub(2, @event_id, true)
pbMessage("Hi! We're giving out this fun accessory for this special day. Enjoy!")
obtainHat(HAT_CLOWN)
end
end
end

View File

@@ -0,0 +1,10 @@
def isPlayerMale()
return pbGet(VAR_TRAINER_GENDER) == GENDER_MALE
end
def isPlayerFemale()
return pbGet(VAR_TRAINER_GENDER) == GENDER_FEMALE
end# frozen_string_literal: true

View File

@@ -0,0 +1,515 @@
def replaceFusionSpecies(pokemon, speciesToChange, newSpecies)
currentBody = pokemon.species_data.get_body_species_symbol()
currentHead = pokemon.species_data.get_head_species_symbol()
should_update_body = currentBody == speciesToChange
should_update_head = currentHead == speciesToChange
echoln speciesToChange
echoln currentBody
echoln currentHead
return if !should_update_body && !should_update_head
newSpeciesBody = should_update_body ? newSpecies : currentBody
newSpeciesHead = should_update_head ? newSpecies : currentHead
newSpecies = getFusionSpecies(newSpeciesBody, newSpeciesHead)
echoln newSpecies.id_number
pokemon.species = newSpecies
end
def changeSpeciesSpecific(pokemon, newSpecies)
pokemon.species = newSpecies
$player.pokedex.set_seen(newSpecies)
$player.pokedex.set_owned(newSpecies)
end
def setPokemonMoves(pokemon, move_ids = [])
moves = []
move_ids.each { |move_id|
moves << Pokemon::Move.new(move_id)
}
pokemon.moves = moves
end
def getGenericPokemonCryText(pokemonSpecies)
case pokemonSpecies
when 25
return "Pika!"
when 16, 17, 18, 21, 22, 144, 145, 146, 227, 417, 418, 372 # birds
return "Squawk!"
when 163, 164
return "Hoot!" # owl
else
return "Guaugh!"
end
end
def Kernel.getPlateType(item)
return :FIGHTING if item == PBItems::FISTPLATE
return :FLYING if item == PBItems::SKYPLATE
return :POISON if item == PBItems::TOXICPLATE
return :GROUND if item == PBItems::EARTHPLATE
return :ROCK if item == PBItems::STONEPLATE
return :BUG if item == PBItems::INSECTPLATE
return :GHOST if item == PBItems::SPOOKYPLATE
return :STEEL if item == PBItems::IRONPLATE
return :FIRE if item == PBItems::FLAMEPLATE
return :WATER if item == PBItems::SPLASHPLATE
return :GRASS if item == PBItems::MEADOWPLATE
return :ELECTRIC if item == PBItems::ZAPPLATE
return :PSYCHIC if item == PBItems::MINDPLATE
return :ICE if item == PBItems::ICICLEPLATE
return :DRAGON if item == PBItems::DRACOPLATE
return :DARK if item == PBItems::DREADPLATE
return :FAIRY if item == PBItems::PIXIEPLATE
return -1
end
def Kernel.listPlatesInBag()
list = []
list << PBItems::FISTPLATE if $PokemonBag.pbQuantity(:FISTPLATE) >= 1
list << PBItems::SKYPLATE if $PokemonBag.pbQuantity(:SKYPLATE) >= 1
list << PBItems::TOXICPLATE if $PokemonBag.pbQuantity(:TOXICPLATE) >= 1
list << PBItems::EARTHPLATE if $PokemonBag.pbQuantity(:EARTHPLATE) >= 1
list << PBItems::STONEPLATE if $PokemonBag.pbQuantity(:STONEPLATE) >= 1
list << PBItems::INSECTPLATE if $PokemonBag.pbQuantity(:INSECTPLATE) >= 1
list << PBItems::SPOOKYPLATE if $PokemonBag.pbQuantity(:SPOOKYPLATE) >= 1
list << PBItems::IRONPLATE if $PokemonBag.pbQuantity(:IRONPLATE) >= 1
list << PBItems::FLAMEPLATE if $PokemonBag.pbQuantity(:FLAMEPLATE) >= 1
list << PBItems::SPLASHPLATE if $PokemonBag.pbQuantity(:SPLASHPLATE) >= 1
list << PBItems::MEADOWPLATE if $PokemonBag.pbQuantity(:MEADOWPLATE) >= 1
list << PBItems::ZAPPLATE if $PokemonBag.pbQuantity(:ZAPPLATE) >= 1
list << PBItems::MINDPLATE if $PokemonBag.pbQuantity(:MINDPLATE) >= 1
list << PBItems::ICICLEPLATE if $PokemonBag.pbQuantity(:ICICLEPLATE) >= 1
list << PBItems::DRACOPLATE if $PokemonBag.pbQuantity(:DRACOPLATE) >= 1
list << PBItems::DREADPLATE if $PokemonBag.pbQuantity(:DREADPLATE) >= 1
list << PBItems::PIXIEPLATE if $PokemonBag.pbQuantity(:PIXIEPLATE) >= 1
return list
end
def getArceusPlateType(heldItem)
return :NORMAL if heldItem == nil
case heldItem
when :FISTPLATE
return :FIGHTING
when :SKYPLATE
return :FLYING
when :TOXICPLATE
return :POISON
when :EARTHPLATE
return :GROUND
when :STONEPLATE
return :ROCK
when :INSECTPLATE
return :BUG
when :SPOOKYPLATE
return :GHOST
when :IRONPLATE
return :STEEL
when :FLAMEPLATE
return :FIRE
when :SPLASHPLATE
return :WATER
when :MEADOWPLATE
return :GRASS
when :ZAPPLATE
return :ELECTRIC
when :MINDPLATE
return :PSYCHIC
when :ICICLEPLATE
return :ICE
when :DRACOPLATE
return :DRAGON
when :DREADPLATE
return :DARK
when :PIXIEPLATE
return :FAIRY
else
return :NORMAL
end
end
def changeOricorioForm(pokemon, form = nil)
oricorio_forms = [:ORICORIO_1, :ORICORIO_2, :ORICORIO_3, :ORICORIO_4]
body_id = pokemon.isFusion? ? get_body_species_from_symbol(pokemon.species) : pokemon.species
head_id = pokemon.isFusion? ? get_head_species_from_symbol(pokemon.species) : pokemon.species
oricorio_body = oricorio_forms.include?(body_id)
oricorio_head = oricorio_forms.include?(head_id)
if form == 1
body_id = :ORICORIO_1 if oricorio_body
head_id = :ORICORIO_1 if oricorio_head
elsif form == 2
body_id = :ORICORIO_2 if oricorio_body
head_id = :ORICORIO_2 if oricorio_head
elsif form == 3
body_id = :ORICORIO_3 if oricorio_body
head_id = :ORICORIO_3 if oricorio_head
elsif form == 4
body_id = :ORICORIO_4 if oricorio_body
head_id = :ORICORIO_4 if oricorio_head
else
return false
end
head_number = getDexNumberForSpecies(head_id)
body_number = getDexNumberForSpecies(body_id)
newForm = pokemon.isFusion? ? getSpeciesIdForFusion(head_number, body_number) : head_id
$player.pokedex.set_seen(newForm)
$player.pokedex.set_owned(newForm)
pokemon.species = newForm
return true
end
def changeOricorioFlower(form = 1)
if $PokemonGlobal.stepcount % 25 == 0
if !hatUnlocked?(HAT_FLOWER) && rand(2) == 0
obtainHat(HAT_FLOWER)
$PokemonGlobal.stepcount += 1
else
pbMessage(_INTL("Woah! A Pokémon jumped out of the flower!"))
pbWildBattle(:FOMANTIS, 10)
$PokemonGlobal.stepcount += 1
end
end
return if !($player.has_species_or_fusion?(:ORICORIO_1) || $player.has_species_or_fusion?(:ORICORIO_2) || $player.has_species_or_fusion?(:ORICORIO_3) || $player.has_species_or_fusion?(:ORICORIO_4))
message = ""
form_name = ""
if form == 1
message = "It's a flower with red nectar. "
form_name = "Baile"
elsif form == 2
message = "It's a flower with yellow nectar. "
form_name = "Pom-pom"
elsif form == 3
message = "It's a flower with pink nectar. "
form_name = "Pa'u"
elsif form == 4
message = "It's a flower with blue nectar. "
form_name = "Sensu"
end
message = message + "Show it to a Pokémon?"
if pbConfirmMessage(message)
pbChoosePokemon(1, 2,
proc { |poke|
!poke.egg? &&
(Kernel.isPartPokemon(poke, :ORICORIO_1) ||
Kernel.isPartPokemon(poke, :ORICORIO_2) ||
Kernel.isPartPokemon(poke, :ORICORIO_3) ||
Kernel.isPartPokemon(poke, :ORICORIO_4))
})
if (pbGet(1) != -1)
poke = $player.party[pbGet(1)]
if changeOricorioForm(poke, form)
pbMessage(_INTL("{1} switched to the {2} style", poke.name, form_name))
pbSet(1, poke.name)
else
pbMessage(_INTL("{1} remained the same...", poke.name, form_name))
end
end
end
end
def oricorioEventPickFlower(flower_color)
quest_progression = pbGet(VAR_ORICORIO_FLOWERS)
if flower_color == :PINK
if !$game_switches[SWITCH_ORICORIO_QUEST_PINK]
pbMessage(_INTL("Woah! A Pokémon jumped out of the flower!"))
pbWildBattle(:FOMANTIS, 10)
end
$game_switches[SWITCH_ORICORIO_QUEST_PINK] = true
pbMessage(_INTL("It's a flower with pink nectar."))
pbSEPlay("MiningAllFound")
pbMessage(_INTL("{1} picked some of the pink flowers.", $player.name))
elsif flower_color == :RED && quest_progression == 1
$game_switches[SWITCH_ORICORIO_QUEST_RED] = true
pbMessage(_INTL("It's a flower with red nectar."))
pbSEPlay("MiningAllFound")
pbMessage(_INTL("{1} picked some of the red flowers.", $player.name))
elsif flower_color == :BLUE && quest_progression == 2
$game_switches[SWITCH_ORICORIO_QUEST_BLUE] = true
pbMessage(_INTL("It's a flower with blue nectar."))
pbSEPlay("MiningAllFound")
pbMessage(_INTL("{1} picked some of the blue flowers.", $player.name))
end
end
# frozen_string_literal: true
def isInKantoGeneration(dexNumber)
return dexNumber <= 151
end
def isKantoPokemon(species)
dexNum = getDexNumberForSpecies(species)
poke = getPokemon(species)
head_dex = getDexNumberForSpecies(poke.get_head_species())
body_dex = getDexNumberForSpecies(poke.get_body_species())
return isInKantoGeneration(dexNum) || isInKantoGeneration(head_dex) || isInKantoGeneration(body_dex)
end
def isInJohtoGeneration(dexNumber)
return dexNumber > 151 && dexNumber <= 251
end
def isJohtoPokemon(species)
dexNum = getDexNumberForSpecies(species)
poke = getPokemon(species)
head_dex = getDexNumberForSpecies(poke.get_head_species())
body_dex = getDexNumberForSpecies(poke.get_body_species())
return isInJohtoGeneration(dexNum) || isInJohtoGeneration(head_dex) || isInJohtoGeneration(body_dex)
end
def isAlolaPokemon(species)
dexNum = getDexNumberForSpecies(species)
poke = getPokemon(species)
head_dex = getDexNumberForSpecies(poke.get_head_species())
body_dex = getDexNumberForSpecies(poke.get_body_species())
list = [
370, 373, 430, 431, 432, 433, 450, 451, 452,
453, 454, 455, 459, 460, 463, 464, 465, 469, 470,
471, 472, 473, 474, 475, 476, 477, 498, 499,
]
return list.include?(dexNum) || list.include?(head_dex) || list.include?(body_dex)
end
def isKalosPokemon(species)
dexNum = getDexNumberForSpecies(species)
poke = getPokemon(species)
head_dex = getDexNumberForSpecies(poke.get_head_species())
body_dex = getDexNumberForSpecies(poke.get_body_species())
list =
[327, 328, 329, 339, 371, 372, 417, 418,
425, 426, 438, 439, 440, 441, 444, 445, 446,
456, 461, 462, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487,
489, 490, 491, 492, 500,
]
return list.include?(dexNum) || list.include?(head_dex) || list.include?(body_dex)
end
def isUnovaPokemon(species)
dexNum = getDexNumberForSpecies(species)
poke = getPokemon(species)
head_dex = getDexNumberForSpecies(poke.get_head_species())
body_dex = getDexNumberForSpecies(poke.get_body_species())
list =
[
330, 331, 337, 338, 348, 349, 350, 351, 359, 360, 361,
362, 363, 364, 365, 366, 367, 368, 369, 374, 375, 376, 377,
397, 398, 399, 406, 407, 408, 409, 410, 411, 412, 413, 414,
415, 416, 419, 420,
422, 423, 424, 434, 345,
466, 467, 494, 493,
]
return list.include?(dexNum) || list.include?(head_dex) || list.include?(body_dex)
end
def isSinnohPokemon(species)
dexNum = getDexNumberForSpecies(species)
poke = getPokemon(species)
head_dex = getDexNumberForSpecies(poke.get_head_species())
body_dex = getDexNumberForSpecies(poke.get_body_species())
list =
[254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265,
266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 288, 294,
295, 296, 297, 298, 299, 305, 306, 307, 308, 315, 316, 317,
318, 319, 320, 321, 322, 323, 324, 326, 332, 343, 344, 345,
346, 347, 352, 353, 354, 358, 383, 384, 388, 389, 400, 402,
403, 429, 468]
return list.include?(dexNum) || list.include?(head_dex) || list.include?(body_dex)
end
def isHoennPokemon(species)
dexNum = getDexNumberForSpecies(species)
poke = getPokemon(species)
head_dex = getDexNumberForSpecies(poke.get_head_species())
body_dex = getDexNumberForSpecies(poke.get_body_species())
list = [252, 253, 276, 277, 278, 279, 280, 281, 282, 283, 284,
285, 286, 287, 289, 290, 291, 292, 293, 300, 301, 302, 303,
304, 309, 310, 311, 312, 313, 314, 333, 334, 335, 336, 340,
341, 342, 355, 356, 357, 378, 379, 380, 381, 382, 385, 386,
387, 390, 391, 392, 393, 394, 395, 396, 401, 404, 405, 421,
427, 428, 436, 437, 442, 443, 447, 448, 449, 457, 458, 488,
495, 496, 497, 501, 502, 503, 504, 505, 506, 507, 508, 509,
510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521,
522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533,
534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545,
546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557,
558, 559, 560, 561, 562, 563, 564, 565
]
return list.include?(dexNum) || list.include?(head_dex) || list.include?(body_dex)
end
def Kernel.getRoamingMap(roamingArrayPos)
curmap = $PokemonGlobal.roamPosition[roamingArrayPos]
mapinfos = $RPGVX ? load_data("Data/MapInfos.rvdata") : load_data("Data/MapInfos.rxdata")
text = mapinfos[curmap].name #,(curmap==$game_map.map_id) ? _INTL("(this map)") : "")
return text
end
def get_default_moves_at_level(species, level)
moveset = GameData::Species.get(species).moves
knowable_moves = []
moveset.each { |m| knowable_moves.push(m[1]) if m[0] <= level }
# Remove duplicates (retaining the latest copy of each move)
knowable_moves = knowable_moves.reverse
knowable_moves |= []
knowable_moves = knowable_moves.reverse
# Add all moves
moves = []
first_move_index = knowable_moves.length - MAX_MOVES
first_move_index = 0 if first_move_index < 0
for i in first_move_index...knowable_moves.length
#moves.push(Pokemon::Move.new(knowable_moves[i]))
moves << knowable_moves[i]
end
return moves
end
def listPokemonIDs()
for id in 0..Settings::NB_POKEMON
pokemon = GameData::Species.get(id).species
echoln id.to_s + ": " + "\"" + pokemon.to_s + "\"" + ", "
end
end
def getAllNonLegendaryPokemon()
list = []
for i in 1..143
list.push(i)
end
for i in 147..149
list.push(i)
end
for i in 152..242
list.push(i)
end
list.push(246)
list.push(247)
list.push(248)
for i in 252..314
list.push(i)
end
for i in 316..339
list.push(i)
end
for i in 352..377
list.push(i)
end
for i in 382..420
list.push(i)
end
return list
end
def getPokemonEggGroups(species)
return GameData::Species.get(species).egg_groups
end
def getAbilityIndexFromID(abilityID, fusedPokemon)
abilityList = fusedPokemon.getAbilityList
for abilityArray in abilityList #ex: [:CHLOROPHYLL, 0]
ability = abilityArray[0]
index = abilityArray[1]
return index if ability == abilityID
end
return 0
end
def getSpecies(dexnum)
return getPokemon(dexnum.species) if dexnum.is_a?(Pokemon)
return getPokemon(dexnum)
end
def getPokemon(dexNum)
if dexNum.is_a?(Integer)
if dexNum > Settings::NB_POKEMON
body_id = getBodyID(dexNum)
head_id = getHeadID(dexNum, body_id)
pokemon_id = getFusedPokemonIdFromDexNum(body_id, head_id)
else
pokemon_id = dexNum
end
else
pokemon_id = dexNum
end
return GameData::Species.get(pokemon_id)
end
def CanLearnMove(pokemon, move)
species = getID(PBSpecies, pokemon)
return false if species <= 0
data = load_data("Data/tm.dat")
return false if !data[move]
return data[move].any? { |item| item == species }
end
def getID(pbspecies_unused, species)
if species.is_a?(String)
return nil
elsif species.is_a?(Symbol)
return GameData::Species.get(species).id_number
elsif species.is_a?(Pokemon)
id = species.dexNum
end
end
def pbAddPokemonID(pokemon_id, level = 1, see_form = true, skip_randomize = false)
return false if !pokemon_id
skip_randomize = true if $game_switches[SWITCH_CHOOSING_STARTER] #when choosing starters
if pbBoxesFull?
pbMessage(_INTL("There's no more room for Pokémon!\1"))
pbMessage(_INTL("The Pokémon Boxes are full and can't accept any more!"))
return false
end
if pokemon_id.is_a?(Integer) && level.is_a?(Integer)
pokemon = Pokemon.new(pokemon_id, level)
species_name = pokemon.speciesName
end
#random species if randomized gift pokemon & wild poke
if $game_switches[SWITCH_RANDOM_GIFT_POKEMON] && $game_switches[SWITCH_RANDOM_WILD] && !skip_randomize
tryRandomizeGiftPokemon(pokemon, skip_randomize)
end
pbMessage(_INTL("{1} obtained {2}!\\me[Pkmn get]\\wtnp[80]\1", $Trainer.name, species_name))
pbNicknameAndStore(pokemon)
$Trainer.pokedex.register(pokemon) if see_form
return true
end
def pbHasSpecies?(species)
if species.is_a?(String) || species.is_a?(Symbol)
id = getID(PBSpecies, species)
elsif species.is_a?(Pokemon)
id = species.dexNum
end
for pokemon in $Trainer.party
next if pokemon.isEgg?
return true if pokemon.dexNum == id
end
return false
end
def pbPlayCry(pkmn, volume = 90, pitch = nil)
GameData::Species.play_cry(pkmn, volume, pitch)
end
def pbCryFrameLength(species, form = 0, pitch = 100)
return GameData::Species.cry_length(species, form, pitch)
end

View File

@@ -0,0 +1,102 @@
def fixMissedHMs()
# Flash
if $PokemonBag.pbQuantity(:HM08) < 1 && $PokemonGlobal.questRewardsObtained.include?(:HM08)
pbReceiveItem(:HM08)
end
# Cut
if $PokemonBag.pbQuantity(:HM01) < 1 && $game_switches[SWITCH_SS_ANNE_DEPARTED]
pbReceiveItem(:HM01)
end
# Strength
if $PokemonBag.pbQuantity(:HM04) < 1 && $game_switches[SWITCH_SNORLAX_GONE_ROUTE_12]
pbReceiveItem(:HM04)
end
# Surf
if $PokemonBag.pbQuantity(:HM03) < 1 && $game_self_switches[[107, 1, "A"]]
pbReceiveItem(:HM03)
end
# Teleport
if $PokemonBag.pbQuantity(:HM07) < 1 && $game_switches[SWITCH_TELEPORT_NPC]
pbReceiveItem(:HM07)
end
# Fly
if $PokemonBag.pbQuantity(:HM02) < 1 && $game_self_switches[[439, 1, "B"]]
pbReceiveItem(:HM02)
end
# Waterfall
if $PokemonBag.pbQuantity(:HM05) < 1 && $game_switches[SWITCH_GOT_WATERFALL]
pbReceiveItem(:HM05)
end
# Dive
if $PokemonBag.pbQuantity(:HM06) < 1 && $game_switches[SWITCH_GOT_DIVE]
pbReceiveItem(:HM06)
end
# Rock Climb
if $PokemonBag.pbQuantity(:HM10) < 1 && $game_switches[SWITCH_GOT_ROCK_CLIMB]
pbReceiveItem(:HM10)
end
end
def fixFinishedRocketQuests()
fix_broken_TR_quests()
var_tr_missions_cerulean = 288
switch_tr_mission_cerulean_4 = 1116
switch_tr_mission_celadon_1 = 1084
switch_tr_mission_celadon_2 = 1086
switch_tr_mission_celadon_3 = 1088
switch_tr_mission_celadon_4 = 1110
switch_pinkan_done = 1119
nb_cerulean_missions = pbGet(var_tr_missions_cerulean)
finishTRQuest("tr_cerulean_1", :SUCCESS, true) if nb_cerulean_missions >= 1 && !pbCompletedQuest?("tr_cerulean_1")
echoln pbCompletedQuest?("tr_cerulean_1")
finishTRQuest("tr_cerulean_2", :SUCCESS, true) if nb_cerulean_missions >= 2 && !pbCompletedQuest?("tr_cerulean_2")
finishTRQuest("tr_cerulean_3", :SUCCESS, true) if nb_cerulean_missions >= 3 && !pbCompletedQuest?("tr_cerulean_3")
finishTRQuest("tr_cerulean_4", :SUCCESS, true) if $game_switches[switch_tr_mission_cerulean_4] && !pbCompletedQuest?("tr_cerulean_4")
finishTRQuest("tr_celadon_1", :SUCCESS, true) if $game_switches[switch_tr_mission_celadon_1] && !pbCompletedQuest?("tr_celadon_1")
finishTRQuest("tr_celadon_2", :SUCCESS, true) if $game_switches[switch_tr_mission_celadon_2] && !pbCompletedQuest?("tr_celadon_2")
finishTRQuest("tr_celadon_3", :SUCCESS, true) if $game_switches[switch_tr_mission_celadon_3] && !pbCompletedQuest?("tr_celadon_3")
finishTRQuest("tr_celadon_4", :SUCCESS, true) if $game_switches[switch_tr_mission_celadon_4] && !pbCompletedQuest?("tr_celadon_4")
finishTRQuest("tr_pinkan", :SUCCESS, true) if $game_switches[switch_pinkan_done] && !pbCompletedQuest?("tr_pinkan")
end
def fix_broken_TR_quests()
for trainer_quest in $player.quests
if trainer_quest.id == 0 # tr quests were all set to ID 0 instead of their real ID in v 6.4.0
for rocket_quest_id in TR_QUESTS.keys
rocket_quest = TR_QUESTS[rocket_quest_id]
next if !rocket_quest
if trainer_quest.name == rocket_quest.name
trainer_quest.id = rocket_quest_id
end
end
end
end
end
def failAllIncompleteRocketQuests()
for trainer_quest in $player.quests
finishTRQuest("tr_cerulean_1", :FAILURE) if trainer_quest.id == "tr_cerulean_1" && !pbCompletedQuest?("tr_cerulean_1")
finishTRQuest("tr_cerulean_2", :FAILURE) if trainer_quest.id == "tr_cerulean_2" && !pbCompletedQuest?("tr_cerulean_2")
finishTRQuest("tr_cerulean_3", :FAILURE) if trainer_quest.id == "tr_cerulean_3" && !pbCompletedQuest?("tr_cerulean_3")
finishTRQuest("tr_cerulean_4", :FAILURE) if trainer_quest.id == "tr_cerulean_4" && !pbCompletedQuest?("tr_cerulean_4")
finishTRQuest("tr_celadon_1", :FAILURE) if trainer_quest.id == "tr_celadon_1" && !pbCompletedQuest?("tr_celadon_1")
finishTRQuest("tr_celadon_2", :FAILURE) if trainer_quest.id == "tr_celadon_2" && !pbCompletedQuest?("tr_celadon_2")
finishTRQuest("tr_celadon_3", :FAILURE) if trainer_quest.id == "tr_celadon_3" && !pbCompletedQuest?("tr_celadon_3")
finishTRQuest("tr_celadon_4", :FAILURE) if trainer_quest.id == "tr_celadon_4" && !pbCompletedQuest?("tr_celadon_4")
end
end

View File

@@ -0,0 +1,7 @@
#ex:Game_Event.new
# forced_sprites = {"1.133" => "a"}
# setForcedAltSprites(forced_sprites)
#
def setForcedAltSprites(forcedSprites_map)
$game_temp.forced_alt_sprites = forcedSprites_map
end

View File

@@ -0,0 +1,210 @@
# frozen_string_literal: true
# todo: implement
def getMappedKeyFor(internalKey)
keybinding_fileName = "keybindings.mkxp1"
path = System.data_directory + keybinding_fileName
parse_keybindings(path)
# echoln Keybindings.new(path).bindings
end
def formatNumberToString(number)
return number.to_s.reverse.gsub(/(\d{3})(?=\d)/, '\\1,').reverse
end
def playCry(pokemonSpeciesSymbol)
species = GameData::Species.get(pokemonSpeciesSymbol).species
GameData::Species.play_cry_from_species(species)
end
# Get difficulty for displaying in-game
def getDisplayDifficulty
if $game_switches[SWITCH_GAME_DIFFICULTY_EASY] || $player.lowest_difficulty <= 0
return getDisplayDifficultyFromIndex(0)
elsif $player.lowest_difficulty <= 1
return getDisplayDifficultyFromIndex(1)
elsif $game_switches[SWITCH_GAME_DIFFICULTY_HARD]
return getDisplayDifficultyFromIndex(2)
else
return getDisplayDifficultyFromIndex(1)
end
end
def getDisplayDifficultyFromIndex(difficultyIndex)
return "Easy" if difficultyIndex == 0
return "Normal" if difficultyIndex == 1
return "Hard" if difficultyIndex == 2
return "???"
end
def getGameModeFromIndex(index)
return "Classic" if index == 0
return "Random" if index == 1
return "Remix" if index == 2
return "Expert" if index == 3
return "Species" if index == 4
return "Debug" if index == 5
return ""
end
def openUrlInBrowser(url = "")
begin
# Open the URL in the default web browser
system("xdg-open", url) || system("open", url) || system("start", url)
rescue
Input.clipboard = url
pbMessage("The game could not open the link in the browser")
pbMessage("The link has been copied to your clipboard instead")
end
end
def clearAllSelfSwitches(mapID, switch = "A", newValue = false)
map = $MapFactory.getMap(mapID, false)
map.events.each { |event_array|
event_id = event_array[0]
pbSetSelfSwitch(event_id, switch, newValue, mapID)
}
end
def isTuesdayNight()
day = getDayOfTheWeek()
hour = pbGetTimeNow().hour
echoln hour
return (day == :TUESDAY && hour >= 20) || (day == :WEDNESDAY && hour < 5)
end
def setDifficulty(index)
$player.selected_difficulty = index
case index
when 0 # EASY
$game_switches[SWITCH_GAME_DIFFICULTY_EASY] = true
$game_switches[SWITCH_GAME_DIFFICULTY_HARD] = false
when 1 # NORMAL
$game_switches[SWITCH_GAME_DIFFICULTY_EASY] = false
$game_switches[SWITCH_GAME_DIFFICULTY_HARD] = false
when 2 # HARD
$game_switches[SWITCH_GAME_DIFFICULTY_EASY] = false
$game_switches[SWITCH_GAME_DIFFICULTY_HARD] = true
end
end
# Old menu for changing difficulty - unused
def change_game_difficulty(down_only = false)
message = "The game is currently on " + get_difficulty_text() + " difficulty."
pbMessage(message)
choice_easy = "Easy"
choice_normal = "Normal"
choice_hard = "Hard"
choice_cancel = "Cancel"
available_difficulties = []
currentDifficulty = get_current_game_difficulty
if down_only
if currentDifficulty == :HARD
available_difficulties << choice_hard
available_difficulties << choice_normal
available_difficulties << choice_easy
elsif currentDifficulty == :NORMAL
available_difficulties << choice_normal
available_difficulties << choice_easy
elsif currentDifficulty == :EASY
available_difficulties << choice_easy
end
else
available_difficulties << choice_easy
available_difficulties << choice_normal
available_difficulties << choice_hard
end
available_difficulties << choice_cancel
index = pbMessage("Select a new difficulty", available_difficulties, available_difficulties[-1])
choice = available_difficulties[index]
case choice
when choice_easy
$game_switches[SWITCH_GAME_DIFFICULTY_EASY] = true
$game_switches[SWITCH_GAME_DIFFICULTY_HARD] = false
when choice_normal
$game_switches[SWITCH_GAME_DIFFICULTY_EASY] = false
$game_switches[SWITCH_GAME_DIFFICULTY_HARD] = false
when choice_hard
$game_switches[SWITCH_GAME_DIFFICULTY_EASY] = false
$game_switches[SWITCH_GAME_DIFFICULTY_HARD] = true
when choice_cancel
return
end
message = "The game is currently on " + get_difficulty_text() + " difficulty."
pbMessage(message)
end
def find_newer_available_version
latest_Version = fetch_latest_game_version
return nil if !latest_Version
return nil if is_higher_version(Settings::GAME_VERSION_NUMBER, latest_Version)
return latest_Version
end
def is_higher_version(gameVersion, latestVersion)
gameVersion_parts = gameVersion.split('.').map(&:to_i)
latestVersion_parts = latestVersion.split('.').map(&:to_i)
# Compare each part of the version numbers from left to right
gameVersion_parts.each_with_index do |part, i|
return true if (latestVersion_parts[i].nil? || part > latestVersion_parts[i])
return false if part < latestVersion_parts[i]
end
return latestVersion_parts.length <= gameVersion_parts.length
end
def get_current_game_difficulty
return :EASY if $game_switches[SWITCH_GAME_DIFFICULTY_EASY]
return :HARD if $game_switches[SWITCH_GAME_DIFFICULTY_HARD]
return :NORMAL
end
def get_difficulty_text
if $game_switches[SWITCH_GAME_DIFFICULTY_EASY]
return "Easy"
elsif $game_switches[SWITCH_GAME_DIFFICULTY_HARD]
return "Hard"
else
return "Normal"
end
end
def getCurrentLevelCap()
current_max_level = Settings::LEVEL_CAPS[$Trainer.badge_count]
current_max_level *= Settings::HARD_MODE_LEVEL_MODIFIER if $game_switches[SWITCH_GAME_DIFFICULTY_HARD]
return current_max_level
end
def pokemonExceedsLevelCap(pokemon)
return false if $Trainer.badge_count >= Settings::NB_BADGES
current_max_level = getCurrentLevelCap()
return pokemon.level >= current_max_level
end
def getLatestSpritepackDate()
return Time.new(Settings::NEWEST_SPRITEPACK_YEAR, Settings::NEWEST_SPRITEPACK_MONTH)
end
def new_spritepack_was_released()
current_spritepack_date = $PokemonGlobal.current_spritepack_date
latest_spritepack_date = getLatestSpritepackDate()
if !current_spritepack_date || (current_spritepack_date < latest_spritepack_date)
$PokemonGlobal.current_spritepack_date = latest_spritepack_date
return true
end
return false
end
def pbGetSelfSwitch(eventId, switch)
return $game_self_switches[[@map_id, eventId, switch]]
end

View File

@@ -0,0 +1,34 @@
SWITCH_GYM_RANDOM_EACH_BATTLE=668
SWITCH_NO_BUMP_SOUND=108
SWITCH_HAS_PREVIOUS_SAVEFILE = 972
VARIABLE_BATTLE_STYLE = 199
def setup_new_game()
set_new_game_switches
set_new_game_variables
setup_player
setup_randomizer
end
def set_new_game_switches
$game_switches[SWITCH_GYM_RANDOM_EACH_BATTLE] = true
$game_switches[SWITCH_NO_BUMP_SOUND] = true
$game_switches[SWITCH_HAS_PREVIOUS_SAVEFILE]= SaveData.exists?
end
def set_new_game_variables
pbSet(VARIABLE_BATTLE_STYLE,0)
end
def setup_player
$player.has_running_shoes=true
#pbChangePlayer(0)
end
def setup_randomizer
#init the random items hash even if it's not used
#pbShuffleItems
#pbShuffleTMs
end

View File

@@ -0,0 +1,118 @@
class TilemapRenderer
alias original_tilemapRenderer_initialize initialize
def initialize(viewport)
original_tilemapRenderer_initialize(viewport)
@custom_autotile_ids = {} # key: tile_id, value: filename
end
# Examples:
#
# Normal tile IDs start at 384
#
# 1 => [["Sand shore"], ["Flowers2"]],
# 2 => [[], ["Flowers2", "Waterfall", "Waterfall crest", "Waterfall bottom"]],
# 6 => [["Water rock", "Sea deep"], []]
EXTRA_AUTOTILES = {
1 => { #route-field
996 => "flowers_orange[10]",
991 => "flowers_pink[10]",
999 => "flowers_yellow[10]",
1007 => "flowers_blue[10]",
1015 => "flowers_purple[10]",
1023 => "flowers_red[10]",
1031 => "flowers_grey[10]",
1039 => "flowers_white[10]",
},
2 => { #small-town
996 => "flowers_orange[10]",
991 => "flowers_pink[10]",
999 => "flowers_yellow[10]",
1007 => "flowers_blue[10]",
1015 => "flowers_purple[10]",
1023 => "flowers_red[10]",
1031 => "flowers_grey[10]",
1039 => "flowers_white[10]",
},
3 => { #interior
385 => "tv_flicker_left",
}
}
def add_extra_autotiles(tileset_id)
overrides = EXTRA_AUTOTILES[tileset_id]
return unless overrides
overrides.each do |tile_id, filename|
@autotiles.add(filename)
@custom_autotile_ids[tile_id] = filename
end
end
def remove_extra_autotiles(tileset_id)
return if !EXTRA_AUTOTILES[tileset_id]
EXTRA_AUTOTILES[tileset_id].each do |arr|
arr.each { |filename| remove_autotile(filename) }
end
end
def refresh_tile_bitmap(tile, map, tile_id)
tile.tile_id = tile_id
if tile_id < TILES_PER_AUTOTILE
tile.set_bitmap("", tile_id, false, false, 0, nil)
tile.shows_reflection = false
tile.bridge = false
else
terrain_tag = map.terrain_tags[tile_id] || 0
terrain_tag_data = GameData::TerrainTag.try_get(terrain_tag)
priority = map.priorities[tile_id] || 0
single_autotile_start_id = TILESET_START_ID
true_tileset_start_id = TILESET_START_ID
filename = nil
extra_autotile_hash = EXTRA_AUTOTILES[map.tileset_id]
if extra_autotile_hash && extra_autotile_hash[tile_id]
# Custom tile_id override
filename = extra_autotile_hash[tile_id]
tile.set_bitmap(filename, tile_id, true, @autotiles.animated?(filename),
priority, @autotiles[filename])
elsif tile_id < true_tileset_start_id
# Default behavior
if tile_id < TILESET_START_ID # Real autotiles
filename = map.autotile_names[(tile_id / TILES_PER_AUTOTILE) - 1]
elsif tile_id < single_autotile_start_id # Large extra autotiles
filename = extra_autotile_arrays[0][(tile_id - TILESET_START_ID) / TILES_PER_AUTOTILE]
else
# Single extra autotiles
filename = extra_autotile_arrays[1][tile_id - single_autotile_start_id]
end
tile.set_bitmap(filename, tile_id, true, @autotiles.animated?(filename),
priority, @autotiles[filename])
else
filename = map.tileset_name
tile.set_bitmap(filename, tile_id, false, false, priority, @tilesets[filename])
end
tile.shows_reflection = terrain_tag_data&.shows_reflections
tile.bridge = terrain_tag_data&.bridge
end
refresh_tile_src_rect(tile, tile_id)
end
def refresh_tile_z(tile, map, y, layer, tile_id)
if false#tile.shows_reflection
tile.z = -2000
elsif tile.bridge && $PokemonGlobal.bridge > 0
tile.z = 0
else
priority = tile.priority
tile.z = (priority == 0) ? 0 : (y * SOURCE_TILE_HEIGHT) + (priority * SOURCE_TILE_HEIGHT) + SOURCE_TILE_HEIGHT + 1
end
end
end

View File

@@ -0,0 +1,672 @@
# frozen_string_literal: true
#==============================================================================#
# Pokémon Essentials #
# Version 19.1.dev #
# https://github.com/Maruno17/pokemon-essentials #
#==============================================================================#
module Settings
# The version of your game. It has to adhere to the MAJOR.MINOR.PATCH format.
GAME_VERSION = '6.5.1'
GAME_VERSION_NUMBER = "6.5.1"
LATEST_GAME_RELEASE = "6.5"
POKERADAR_LIGHT_ANIMATION_RED_ID = 17
POKERADAR_LIGHT_ANIMATION_GREEN_ID = 18
POKERADAR_HIDDEN_ABILITY_POKE_CHANCE = 32
POKERADAR_BATTERY_STEPS = 0
LEADER_VICTORY_MUSIC="Battle victory leader"
TRAINER_VICTORY_MUSIC="trainer-victory"
WILD_VICTORY_MUSIC="wild-victory"
#getRandomCustomFusionForIntro
FUSION_ICON_SPRITE_OFFSET = 10
#Infinite fusion settings
NB_POKEMON = 565
CUSTOM_BASE_SPRITES_FOLDER = "Graphics/CustomBattlers/local_sprites/BaseSprites/"
CUSTOM_BATTLERS_FOLDER = "Graphics/CustomBattlers/"
CUSTOM_SPRITES_TO_IMPORT_FOLDER = "Graphics/CustomBattlers/Sprites to import/"
CUSTOM_BATTLERS_FOLDER_INDEXED = "Graphics/CustomBattlers/local_sprites/indexed/"
CUSTOM_BASE_SPRITE_FOLDER = "Graphics/CustomBattlers/local_sprites/BaseSprites/"
BATTLERS_FOLDER = "Graphics/Battlers/Autogens/"
DOWNLOADED_SPRITES_FOLDER = "Graphics/temp/"
DEFAULT_SPRITE_PATH = "Graphics/Battlers/Special/000.png"
CREDITS_FILE_PATH = "Data/sprites/Sprite Credits.csv"
VERSION_FILE_PATH = "Data/VERSION"
CUSTOM_SPRITES_FILE_PATH = "Data/sprites/CUSTOM_SPRITES"
BASE_SPRITES_FILE_PATH = "Data/sprites/BASE_SPRITES"
CUSTOM_DEX_ENTRIES_PATH = "Data/pokedex/dex.json"
AI_DEX_ENTRIES_PATH = "Data/pokedex/generated_entries.json"
POKEDEX_ENTRIES_PATH = "Data/pokedex/all_entries.json"
UPDATED_SPRITESHEETS_CACHE = "Data/sprites/updated_spritesheets_cache"
BACK_ITEM_ICON_PATH = "Graphics/Items/back.png"
PLAYER_GRAPHICS_FOLDER = "Graphics/Characters/player/"
PLAYER_HAT_FOLDER = 'hat'
PLAYER_HAIR_FOLDER = 'hair'
PLAYER_CLOTHES_FOLDER = 'clothes'
PLAYER_BALL_FOLDER = 'balls'
PLAYER_TEMP_OUTFIT_FALLBACK = 'temp'
HATS_DATA_PATH = "Data/outfits/hats_data.json"
HAIRSTYLE_DATA_PATH = "Data/outfits/hairstyles_data.json"
CLOTHES_DATA_PATH = "Data/outfits/clothes_data.json"
PLAYER_SURFBASE_FOLDER = 'surf_base/'
OW_SHINE_ANIMATION_ID=25
HTTP_CONFIGS_FILE_URL = "https://raw.githubusercontent.com/infinitefusion/pif-downloadables/refs/heads/master/Settings.rb"
HTTP_CONFIGS_FILE_PATH = "Data/Scripts/DownloadedSettings.rb"
SPRITES_FILE_URL = "https://raw.githubusercontent.com/infinitefusion/infinitefusion-e18/main/Data/sprites/CUSTOM_SPRITES"
BASE_SPRITES_FILE_URL = "https://raw.githubusercontent.com/infinitefusion/infinitefusion-e18/main/Data/sprites/BASE_SPRITES"
CREDITS_FILE_URL = "https://infinitefusion.net/Sprite Credits.csv"
CUSTOM_DEX_FILE_URL = "https://raw.githubusercontent.com/infinitefusion/pif-downloadables/refs/heads/master/dex.json"
STARTUP_MESSAGES = ""
LEVEL_CAPS=[12,22,26,35,38,45,51,54,62,62,63,64,64,65,67,68]
CUSTOM_ENTRIES_NAME_PLACEHOLDER = "POKENAME"
DEFAULT_SPEED_UP_SPEED=2
FRONTSPRITE_POSITION_OFFSET = 20
FRONTSPRITE_SCALE = 0.6666666666666666
BACKRPSPRITE_SCALE = 1
EGGSPRITE_SCALE = 1
BACKSPRITE_POSITION_OFFSET = 20
FRONTSPRITE_POSITION = 200
SHINY_HUE_OFFSET = 75
NO_LEVEL_MODE_LEVEL_INCR = 5.8
NO_LEVEL_MODE_LEVEL_BASE = 6
SAVEFILE_NB_BACKUPS=10
DISCORD_URL = "https://discord.com/invite/infinitefusion"
WIKI_URL = "https://infinitefusion.fandom.com/"
AI_ENTRIES_URL = "https://ai-entries.pkmninfinitefusion.workers.dev/"
AI_ENTRIES_RATE_MAX_NB_REQUESTS = 10 #Nb. requests allowed in each time window
AI_ENTRIES_RATE_TIME_WINDOW = 120 # In seconds
AI_ENTRIES_RATE_LOG_FILE = 'Data/pokedex/dex_rate_limit.log' # Path to the log file
CUSTOMSPRITES_RATE_MAX_NB_REQUESTS = 15 #Nb. requests allowed in each time window
CUSTOMSPRITES_ENTRIES_RATE_TIME_WINDOW = 120 # In seconds
CUSTOMSPRITES_RATE_LOG_FILE = 'Data/sprites/sprites_rate_limit.log' # Path to the log file
MAX_NB_SPRITES_TO_DOWNLOAD_AT_ONCE=5
CUSTOM_SPRITES_REPO_URL = "https://bitbucket.org/infinitefusionsprites/customsprites/raw/main/CustomBattlers/"
CUSTOM_SPRITES_NEW_URL = "https://infinitefusion.net/CustomBattlers/"
BASE_POKEMON_ALT_SPRITES_REPO_URL = "https://bitbucket.org/infinitefusionsprites/customsprites/raw/main/Other/BaseSprites/"
BASE_POKEMON_ALT_SPRITES_NEW_URL = "https://infinitefusion.net/Other/BaseSprites/"
BASE_POKEMON_SPRITESHEET_URL = "https://infinitefusion.net/spritesheets/spritesheets_base/"
CUSTOM_FUSIONS_SPRITESHEET_URL = "https://infinitefusion.net/spritesheets/spritesheets_custom/"
BASE_POKEMON_SPRITESHEET_TRUE_SIZE_URL = ""
CUSTOM_FUSIONS_SPRITESHEET_TRUE_SIZE_URL = ""
RIVAL_STARTER_PLACEHOLDER_SPECIES = :MEW #(MEW)
VAR_1_PLACEHOLDER_SPECIES = :DIALGA
VAR_2_PLACEHOLDER_SPECIES = :PALKIA
VAR_3_PLACEHOLDER_SPECIES = :GIRATINA
RIVAL_STARTER_PLACEHOLDER_VARIABLE = 250
OVERRIDE_BATTLE_LEVEL_SWITCH = 785
OVERRIDE_BATTLE_LEVEL_VALUE_VAR = 240
HARD_MODE_LEVEL_MODIFIER = 1.1
ZAPMOLCUNO_NB = 999999#176821
MAPS_WITHOUT_SURF_MUSIC = [762]
WONDERTRADE_BASE_URL = "http://localhost:8080"
WONDERTRADE_PUBLIC_KEY = "http://localhost:8080"
MAX_NB_OUTFITS=99
OUTFIT_PREVIEW_PICTURE_ID=20
DEFAULT_TRAINER_CARD_BG="BLUE"
# The generation that the battle system follows. Used throughout the battle
# scripts, and also by some other settings which are used in and out of battle
# (you can of course change those settings to suit your game).
# Note that this isn't perfect. Essentials doesn't accurately replicate every
# single generation's mechanics. It's considered to be good enough. Only
# generations 5 and later are reasonably supported.
MECHANICS_GENERATION = 5
#=============================================================================
# The default screen width (at a scale of 1.0).
SCREEN_WIDTH = 512
# The default screen height (at a scale of 1.0).
SCREEN_HEIGHT = 384
# The default screen scale factor. Possible values are 0.5, 1.0, 1.5 and 2.0.
SCREEN_SCALE = 1.0
FADEOUT_SPEED = 0.2
#=============================================================================
# The maximum level Pokémon can reach.
MAXIMUM_LEVEL = 100
# The level of newly hatched Pokémon.
EGG_LEVEL = 1
# Number of badges in the game
NB_BADGES = 16
# The odds of a newly generated Pokémon being shiny (out of 65536).
SHINY_POKEMON_CHANCE = 16#(MECHANICS_GENERATION >= 6) ? 16 : 8
# The odds of a wild Pokémon/bred egg having Pokérus (out of 65536).
POKERUS_CHANCE = 3
# Whether a bred baby Pokémon can inherit any TM/HM moves from its father. It
# can never inherit TM/HM moves from its mother.
BREEDING_CAN_INHERIT_MACHINE_MOVES = (MECHANICS_GENERATION <= 5)
# Whether a bred baby Pokémon can inherit egg moves from its mother. It can
# always inherit egg moves from its father.
BREEDING_CAN_INHERIT_EGG_MOVES_FROM_MOTHER = (MECHANICS_GENERATION >= 6)
KANTO_STARTERS = [:BULBASAUR, :CHARMANDER, :SQUIRTLE]
JOHTO_STARTERS = [:CHIKORITA, :CYNDAQUIL, :TOTODILE]
HOENN_STARTERS = [:TREECKO, :TORCHIC, :MUDKIP]
SINNOH_STARTERS = [:TURTWIG, :CHIMCHAR, :PIPLUP]
KALOS_STARTERS = [:CHESPIN, :FENNEKIN, :FROAKIE]
#=============================================================================
# The amount of money the player starts the game with.
INITIAL_MONEY = 3000
# The maximum amount of money the player can have.
MAX_MONEY = 999_999
# The maximum number of Game Corner coins the player can have.
MAX_COINS = 99_999
# The maximum number of Battle Points the player can have.
MAX_BATTLE_POINTS = 9_999
# The maximum amount of soot the player can have.
MAX_SOOT = 9_999
# The maximum length, in characters, that the player's name can be.
MAX_PLAYER_NAME_SIZE = 10
# The maximum number of Pokémon that can be in the party.
MAX_PARTY_SIZE = 6
#=============================================================================
# A set of arrays each containing a trainer type followed by a Global Variable
# number. If the variable isn't set to 0, then all trainers with the
# associated trainer type will be named as whatever is in that variable.
RIVAL_NAMES = [
[:RIVAL1, 12],
[:RIVAL2, 12],
[:CHAMPION, 12]
]
#=============================================================================
# Whether outdoor maps should be shaded according to the time of day.
TIME_SHADING = true
#=============================================================================
# Whether poisoned Pokémon will lose HP while walking around in the field.
POISON_IN_FIELD = true #(MECHANICS_GENERATION <= 4)
# Whether poisoned Pokémon will faint while walking around in the field
# (true), or survive the poisoning with 1 HP (false).
POISON_FAINT_IN_FIELD = (MECHANICS_GENERATION >= 3)
# Whether planted berries grow according to Gen 4 mechanics (true) or Gen 3
# mechanics (false).
NEW_BERRY_PLANTS = (MECHANICS_GENERATION >= 4)
# Whether fishing automatically hooks the Pokémon (true), or whether there is
# a reaction test first (false).
FISHING_AUTO_HOOK = false
# The ID of the common event that runs when the player starts fishing (runs
# instead of showing the casting animation).
FISHING_BEGIN_COMMON_EVENT = -1
# The ID of the common event that runs when the player stops fishing (runs
# instead of showing the reeling in animation).
FISHING_END_COMMON_EVENT = -1
#=============================================================================
# The number of steps allowed before a Safari Zone game is over (0=infinite).
SAFARI_STEPS = 600
# The number of seconds a Bug Catching Contest lasts for (0=infinite).
BUG_CONTEST_TIME = 20 * 60 # 20 minutes
#=============================================================================
# Pairs of map IDs, where the location signpost isn't shown when moving from
# one of the maps in a pair to the other (and vice versa). Useful for single
# long routes/towns that are spread over multiple maps.
# e.g. [4,5,16,17,42,43] will be map pairs 4,5 and 16,17 and 42,43.
# Moving between two maps that have the exact same name won't show the
# location signpost anyway, so you don't need to list those maps here.
NO_SIGNPOSTS = []
#=============================================================================
# Whether you need at least a certain number of badges to use some hidden
# moves in the field (true), or whether you need one specific badge to use
# them (false). The amounts/specific badges are defined below.
FIELD_MOVES_COUNT_BADGES = true
# Depending on FIELD_MOVES_COUNT_BADGES, either the number of badges required
# to use each hidden move in the field, or the specific badge number required
# to use each move. Remember that badge 0 is the first badge, badge 1 is the
# second badge, etc.
# e.g. To require the second badge, put false and 1.
# To require at least 2 badges, put true and 2.
BADGE_FOR_CUT = 1
BADGE_FOR_FLASH = 1
BADGE_FOR_ROCKSMASH = 0
BADGE_FOR_SURF = 6
BADGE_FOR_FLY = 3
BADGE_FOR_STRENGTH = 5
BADGE_FOR_DIVE = 9
BADGE_FOR_WATERFALL = 9
BADGE_FOR_TELEPORT = 3
BADGE_FOR_BOUNCE = 8
BADGE_FOR_ROCKCLIMB = 16
#=============================================================================
# If a move taught by a TM/HM/TR replaces another move, this setting is
# whether the machine's move retains the replaced move's PP (true), or whether
# the machine's move has full PP (false).
TAUGHT_MACHINES_KEEP_OLD_PP = (MECHANICS_GENERATION == 5)
# Whether the Black/White Flutes will raise/lower the levels of wild Pokémon
# respectively (true), or will lower/raise the wild encounter rate
# respectively (false).
FLUTES_CHANGE_WILD_ENCOUNTER_LEVELS = (MECHANICS_GENERATION >= 6)
# Whether Repel uses the level of the first Pokémon in the party regardless of
# its HP (true), or it uses the level of the first unfainted Pokémon (false).
REPEL_COUNTS_FAINTED_POKEMON = (MECHANICS_GENERATION >= 6)
# Whether Rage Candy Bar acts as a Full Heal (true) or a Potion (false).
RAGE_CANDY_BAR_CURES_STATUS_PROBLEMS = (MECHANICS_GENERATION >= 7)
#=============================================================================
# The name of the person who created the Pokémon storage system.
def self.storage_creator_name
return _INTL("Bill")
end
# The number of boxes in Pokémon storage.
NUM_STORAGE_BOXES = 40
#=============================================================================
# The names of each pocket of the Bag. Ignore the first entry ("").
def self.bag_pocket_names
return ["",
_INTL("Items"),
_INTL("Medicine"),
_INTL("Poké Balls"),
_INTL("TMs & HMs"),
_INTL("Berries"),
_INTL("Mail"),
_INTL("Battle Items"),
_INTL("Key Items")
]
end
# The maximum number of slots per pocket (-1 means infinite number). Ignore
# the first number (0).
BAG_MAX_POCKET_SIZE = [0, -1, -1, -1, -1, -1, -1, -1, -1]
# The maximum number of items each slot in the Bag can hold.
BAG_MAX_PER_SLOT = 999
# Whether each pocket in turn auto-sorts itself by item ID number. Ignore the
# first entry (the 0).
BAG_POCKET_AUTO_SORT = [0, false, false, false, true, true, false, false, false]
#=============================================================================
# Whether the Pokédex list shown is the one for the player's current region
# (true), or whether a menu pops up for the player to manually choose which
# Dex list to view if more than one is available (false).
USE_CURRENT_REGION_DEX = false
# The names of the Pokédex lists, in the order they are defined in the PBS
# file "regionaldexes.txt". The last name is for the National Dex and is added
# onto the end of this array (remember that you don't need to use it). This
# array's order is also the order of $player.pokedex.unlocked_dexes, which
# records which Dexes have been unlocked (the first is unlocked by default).
# If an entry is just a name, then the region map shown in the Area page while
# viewing that Dex list will be the region map of the region the player is
# currently in. The National Dex entry should always behave like this.
# If an entry is of the form [name, number], then the number is a region
# number. That region's map will appear in the Area page while viewing that
# Dex list, no matter which region the player is currently in.
def self.pokedex_names
return [
# [_INTL("Kanto Pokédex"), 0]
]
end
# Whether all forms of a given species will be immediately available to view
# in the Pokédex so long as that species has been seen at all (true), or
# whether each form needs to be seen specifically before that form appears in
# the Pokédex (false).
DEX_SHOWS_ALL_FORMS = false
# An array of numbers, where each number is that of a Dex list (in the same
# order as above, except the National Dex is -1). All Dex lists included here
# will begin their numbering at 0 rather than 1 (e.g. Victini in Unova's Dex).
DEXES_WITH_OFFSETS = []
#=============================================================================
# A set of arrays, each containing details of a graphic to be shown on the
# region map if appropriate. The values for each array are as follows:
# * Region number.
# * Game Switch; the graphic is shown if this is ON (non-wall maps only).
# * X coordinate of the graphic on the map, in squares.
# * Y coordinate of the graphic on the map, in squares.
# * Name of the graphic, found in the Graphics/Pictures folder.
# * The graphic will always (true) or never (false) be shown on a wall map.
REGION_MAP_EXTRAS = [
#[0, 51, 16, 15, "mapHiddenBerth", false],
#[0, 52, 20, 14, "mapHiddenFaraday", false]
]
TRIPLE_TYPES = [:QMARKS,:ICEFIREELECTRIC,:FIREWATERELECTRIC,:WATERGROUNDFLYING,:GHOSTSTEELWATER,
:FIREWATERGRASS,:GRASSSTEEL,:BUGSTEELPSYCHIC,:ICEROCKSTEEL]
#=============================================================================
# A list of maps used by roaming Pokémon. Each map has an array of other maps
# it can lead to.
ROAMING_AREAS = {
262 => [261,311],
311 => [262,312],
312 => [311],
261 => [262,288,267],
288 => [261,267,285],
267 => [261,288,300,254],
284 => [288,266,285],
300 => [267,254],
254 => [300,265],
266 => [284,265],
265 => [266,254],
285 => [284,288]}
SEVII_ROAMING = {
528 => [526], #Treasure beach
526 => [528,559], #Knot Island
559 => [526,561,564], #Kindle Road
561 => [559], #Mt. Ember
564 => [559,562,563,594], #brine road
562 => [564], #boon island
563 => [564,600] , #kin island
594 => [564,566,603], #water labyrinth
600 => [563,619], #bond bridge
619 => [600] , #Berry forest
566 => [594,603], #Resort gorgeous
603 => [566,594], #Chrono Island
}
# A set of arrays, each containing the details of a roaming Pokémon. The
# information within each array is as follows:
# * Species.
# * Level.
# * Game Switch; the Pokémon roams while this is ON.
# * Encounter type (0=any, 1=grass/walking in cave, 2=surfing, 3=fishing,
# 4=surfing/fishing). See the bottom of PField_RoamingPokemon for lists.
# * Name of BGM to play for that encounter (optional).
# * Roaming areas specifically for this Pokémon (optional).
ROAMING_SPECIES = [
# {
# :species => :LATIAS,
# :level => 30,
# :icon => "pin_latias",
# :game_switch => 53,
# :encounter_type => :all,
# :bgm => "Battle roaming"
# },
# {
# :species => :LATIOS,
# :level => 30,
# :icon => "pin_latios",
# :game_switch => 53,
# :encounter_type => :all,
# :bgm => "Battle roaming"
# },
# {
# :species => :KYOGRE,
# :level => 40,
# :game_switch => 54,
# :encounter_type => :surfing,
# :areas => {
# 2 => [ 21, 31 ],
# 21 => [2, 31, 69],
# 31 => [2, 21, 69],
# 69 => [ 21, 31 ]
# }
# },
# {
# :species => :ENTEI,
# :level => 40,
# :icon => "pin_entei",
# :game_switch => 55,
# :encounter_type => :land
# }
]
PINKAN_ISLAND_MAPS=[51,46,428,531]
#=============================================================================
# A set of arrays, each containing the details of a wild encounter that can
# only occur via using the Poké Radar. The information within each array is as
# follows:
# * Map ID on which this encounter can occur.
# * Probability that this encounter will occur (as a percentage).
# * Species.
# * Minimum possible level.
# * Maximum possible level (optional).
POKE_RADAR_ENCOUNTERS = [
[78, 50, :FLETCHLING,2,5], #Rt. 1
[86, 50, :FLETCHLING,2,5], #Rt. 2
[90, 50, :FLETCHLING,2,5], #Rt. 2
[491, 50, :SHROOMISH,2,5], #Viridian Forest
[490, 50, :BUDEW,4,9], #Rt. 3
[106, 50, :NINCADA,8,10], #Rt. 4
[12, 50, :TOGEPI,10,10], #Rt. 5
[16, 50, :SLAKOTH,12,15], #Rt. 6
[413, 50, :DRIFLOON,17,20], #Rt. 7
[409, 50, :SHINX,17,18], #Rt. 8
[495, 50, :ARON,12,15], #Rt. 9
[351, 50, :ARON,12,15], #Rt. 9
[154, 50, :KLINK,14,17], #Rt. 10
[155, 50, :NINCADA,12,15], #Rt. 11
[159, 50, :COTTONEE,22,25], #Rt. 12
[437, 50, :COTTONEE,22,25], #Rt. 13
[437, 50, :JOLTIK,22,25], #Rt. 13
[440, 50, :JOLTIK,22,25], #Rt. 14
[444, 50, :SOLOSIS,22,25], #Rt. 15
[438, 50, :NATU,22,25], #Rt. 16
[146, 50, :KLEFKI,22,25], #Rt. 17
[517, 50, :FERROSEED,22,25], #Rt. 18
[445, 50, :BAGON,20,20], #Safari zone 1
[484, 50, :AXEW,20,20], #Safari zone 2
[485, 50, :DEINO,20,20], #Safari zone 3
[486, 50, :LARVITAR,20,20], #Safari zone 4
[487, 50, :JANGMOO,20,20], #Safari zone 5
[59, 50, :DUNSPARCE,25,30], #Rt. 21
[171, 50, :BIDOOF,2,5], #Rt. 22
[143, 50, :RIOLU,25,25], #Rt. 23
[8, 50, :BUNEARY,12,13], #Rt. 24
[145, 50, :ABSOL,30,35], #Rt. 26
[147, 50, :ABSOL,30,35], #Rt. 27
[311, 50, :BIDOOF,5,5], #Rt. 29
[284, 50, :LUXIO,40,45], #Rt. 33
[288, 50, :VIGOROTH,40,45], #Rt. 32
[342, 50, :GOLETT,40,45], #Ruins of Alph
[261, 50, :BELLOSSOM,45,50], #Rt. 31
[262, 50, :BIBAREL,45,50], #Rt. 30
[265, 50, :KIRLIA,25,30], #Rt. 34
[254, 50, :SMEARGLE,25,30], #Rt. 35
[267, 50, :SUDOWOODO,25,30], #Rt. 36
[500, 50, :FOMANTIS,30,30], #National Park
[266, 50, :BRELOOM,30,30], #Ilex Forest
[670, 50, :WEAVILE,50,50], #Ice mountains
[528, 50, :PYUKUMUKU,20,20], #Treasure Beach
[690, 50, :OCTILLERY,32,45], #Deep Ocean
[561, 50, :FLETCHINDER,32,45], #Mt. Ember
[562, 50, :NINJASK,45,50], #Boon Island
[603, 50, :KECLEON,45,50], #Chrono Island
[654, 50, :WHIMSICOTT,32,45], #Brine Road
[559, 50, :SCRAGGY,32,45] #Kindle Road
]
#=============================================================================
# The Game Switch that is set to ON when the player blacks out.
STARTING_OVER_SWITCH = 1
# The Game Switch that is set to ON when the player has seen Pokérus in the
# Poké Center (and doesn't need to be told about it again).
SEEN_POKERUS_SWITCH = 2
# The Game Switch which, while ON, makes all wild Pokémon created be shiny.
SHINY_WILD_POKEMON_SWITCH = 31
# The Game Switch which, while ON, makes all Pokémon created considered to be
# met via a fateful encounter.
FATEFUL_ENCOUNTER_SWITCH = 32
#=============================================================================
# ID of the animation played when the player steps on grass (grass rustling).
GRASS_ANIMATION_ID = 1
# ID of the animation played when the player lands on the ground after hopping
# over a ledge (shows a dust impact).
DUST_ANIMATION_ID = 2
# ID of the animation played when a trainer notices the player (an exclamation
# bubble).
EXCLAMATION_ANIMATION_ID = 3
# ID of the animation played when a patch of grass rustles due to using the
# Poké Radar.
RUSTLE_NORMAL_ANIMATION_ID = 1
# ID of the animation played when a patch of grass rustles vigorously due to
# using the Poké Radar. (Rarer species)
RUSTLE_VIGOROUS_ANIMATION_ID = 5
# ID of the animation played when a patch of grass rustles and shines due to
# using the Poké Radar. (Shiny encounter)
RUSTLE_SHINY_ANIMATION_ID = 6
# ID of the animation played when a berry tree grows a stage while the player
# is on the map (for new plant growth mechanics only).
PLANT_SPARKLE_ANIMATION_ID = 7
SLEEP_ANIMATION_ID = 26
CUT_TREE_ANIMATION_ID = 19
ROCK_SMASH_ANIMATION_ID = 20
#=============================================================================
# An array of available languages in the game, and their corresponding message
# file in the Data folder. Edit only if you have 2 or more languages to choose
# from.
LANGUAGES = [
# ["English", "english.dat"],
# ["Deutsch", "deutsch.dat"]
]
#Technical
SPRITE_CACHE_MAX_NB=100
NEWEST_SPRITEPACK_MONTH = 12
NEWEST_SPRITEPACK_YEAR = 2020
#=============================================================================
# Available speech frames. These are graphic files in "Graphics/Windowskins/".
SPEECH_WINDOWSKINS = [
"speech hgss 1",
"speech hgss 2",
"speech hgss 3",
"speech hgss 4",
"speech hgss 5",
"speech hgss 6",
"speech hgss 7",
"speech hgss 8",
"speech hgss 9",
"speech hgss 10",
"speech hgss 11",
"speech hgss 12",
"speech hgss 13",
"speech hgss 14",
"speech hgss 15",
"speech hgss 16",
"speech hgss 17",
"speech hgss 18",
"speech hgss 19",
"speech hgss 20",
"speech pl 18"
]
# Available menu frames. These are graphic files in "Graphics/Windowskins/".
MENU_WINDOWSKINS = [
"default_transparent",
"default_opaque",
"choice 2",
"choice 3",
"choice 4",
"choice 5",
"choice 6",
"choice 7",
"choice 8",
"choice 9",
"choice 10",
"choice 11",
"choice 12",
"choice 13",
"choice 14",
"choice 15",
"choice 16",
"choice 17",
"choice 18",
"choice 19",
"choice 20",
"choice 21",
"choice 22",
"choice 23",
"choice 24",
"choice 25",
"choice 26",
"choice 27",
"choice 28"
]
RANDOMIZED_GYM_TYPE_TM=
{
:NORMAL => [:TM32,:TM49,:TM42,:TM98], #DOUBLETEAM ECHOEDVOICE FACADE BATONPASS
:FIGHTING => [:TM83,:TM115,:TM52,:TM112], #WORKUP POWERUPPUNCH FOCUSBLAST FOCUSPUNCH
:FLYING => [:TM62,:TM58,:TM108,:TM100], #ACROBATICS SKYDROP SKYATTACK DEFOG
:POISON => [:TM84,:TM06,:TM36,:TM34], #POISONJAB TOXIC SLUDGEBOMB SLUDGEWAVE
:GROUND => [:TM28,:TM78,:TM26,:TM119], #DIG BULLDOZE EARTHQUAKE STOMPINGTANTRUM
:ROCK => [:TM39,:TM80,:TM71,:TM69], #ROCKTOMB ROCKTHROW STONEDGE ROCKPOLISH
:BUG => [:TM76,:TM89,:TM113,:TM99], #STRUGGLEBUG UTURN INFESTATION QUIVERDANCE
:GHOST => [:TM85,:TM65,:TM30,:TM97], #DREAMEATER SHADOWCLAW SHADOWBALL NASTYPLOT
:STEEL => [:TM74,:TM118,:TM117,:TM75], # GYROBALL STEELWING SMARTSTRIKE SWORDDANCE
:FIRE => [:TM11,:TM43,:TM38,:TM61], #SUNNYDAY FLAMECHARGE FIREBLAST WILLOWISP
:WATER => [:TM55,:TM105,:TM121,:TM18], #WATERPULSE AQUAJET SCALD RAINDANCE
:GRASS => [:TM22,:TM53,:TM86,:TM102], # SOLARBEAM ENERGYBALL GRASSKNOT SPORE
:ELECTRIC => [:TM73,:TM116,:TM93,:TM72], #THUNDERWAVE SHOCKWAVE WILDCHARGE VOLTSWITCH
:PSYCHIC => [:TM77,:TM03,:TM29,:TM04], #PSYCHUP PSYSHOCK PSYCHIC CALMMIND
:ICE => [:TM110,:TM13,:TM14,:TM07], #AURORAVEIL ICEBEAM BLIZZARD HAIL
:DRAGON => [:TM95,:TM02,:TM82,:TM101], #SNARL DRAGONCLAW DRAGONTAIL DRAGONDANCE
:DARK => [:TM95,:TM46,:TM120,:TM97], #SNARL THIEF THROATCHOP NASTYPLOT
:FAIRY => [:TM45,:TM111,:TM96,:TM104] #ATTRACT DAZZLINGGLEAM MOONBLAST RECOVER
}
EXCLUDE_FROM_RANDOM_SHOPS=[:RARECANDY]
end
# DO NOT EDIT THESE!
module Essentials
VERSION = "19.1.dev"
ERROR_TEXT = ""
end

View File

@@ -0,0 +1,128 @@
# ###################
# ## NEW POKEBALLS #
# ###################
#
# #GENDER BALL (24) - switch le gender du pokemon
# #catch rate: pokeball
# BallHandlers::OnCatch.add(:GENDERBALL,proc{|ball,battle,pokemon|
# if pokemon.gender == 0
# pokemon.makeFemale
# elsif pokemon.gender == 1
# pokemon.makeMale
# end
# })
#
# #BOOST BALL 25 - rend le pokemon traded
# #catch rate: 80% pokeball
# BallHandlers::ModifyCatchRate.add(:TRADEBALL,proc{|ball,catchRate,battle,pokemon|
# catchRate=(catchRate*0.8).floor(1)
# next catchRate
# })
# BallHandlers::OnCatch.add(:TRADEBALL,proc{|ball,battle,pokemon|
# pokemon.obtain_method = 2
# })
#
# #ABILITY BALL 26 - change l'ability
# #catch rate: 60% pokeball
# BallHandlers::ModifyCatchRate.add(:ABILITYBALL,proc{|ball,catchRate,battle,pokemon|
# catchRate=(catchRate*0.6).floor(1)
# next catchRate
# })
# BallHandlers::OnCatch.add(:ABILITYBALL,proc{|ball,battle,pokemon|
# species = getSpecies(dexNum(pokemon))
# ability = species.hidden_abilities[-1]
# pokemon.ability = ability
# pokemon.ability_index= getAbilityIndexFromID(ability,pokemon)
# })
#
# #VIRUS BALL 27 - give pokerus
# #catch rate: 40% pokeball
# BallHandlers::ModifyCatchRate.add(:VIRUSBALL,proc{|ball,catchRate,battle,pokemon|
# catchRate=(catchRate*0.4).floor(1)
# next catchRate
# })
# BallHandlers::OnCatch.add(:VIRUSBALL,proc{|ball,battle,pokemon|
# pokemon.givePokerus
# })
#
# #SHINY BALL 28 - rend shiny
# #catchrate: 20% pokeball
# BallHandlers::ModifyCatchRate.add(:SHINYBALL,proc{|ball,catchRate,battle,pokemon|
# catchRate=(catchRate*0.2).floor(1)
# next catchRate
# })
# BallHandlers::OnCatch.add(:SHINYBALL,proc{|ball,battle,pokemon|
# pokemon.glitter=true
# })
#
# #PERFECTBALL 29
# #catch rate: 10% pokeball
# BallHandlers::ModifyCatchRate.add(:PERFECTBALL,proc{|ball,catchRate,battle,pokemon|
# catchRate=(catchRate*0.1).floor(1)
# next catchRate
# })
# BallHandlers::OnCatch.add(:PERFECTBALL,proc{|ball,battle,pokemon|
# stats = [:ATTACK, :SPECIAL_ATTACK, :SPECIAL_DEFENSE, :SPEED, :DEFENSE, :HP]
# first = rand(stats.length)
# second = rand(stats.length)
# pokemon.iv[stats[first]] = 31
# pokemon.iv[stats[second]] = 31
# })
#
#
# #DREAMBALL - endormi
# BallHandlers::ModifyCatchRate.add(:DREAMBALL,proc{|ball,catchRate,battle,battler|
# battler.status = :SLEEP
# next catchRate
# })
# #TOXICBALL - empoisonné
# BallHandlers::ModifyCatchRate.add(:TOXICBALL,proc{|ball,catchRate,battle,battler|
# battler.status = :POISON
# next catchRate
# })
# #SCORCHBALL - brulé
# BallHandlers::ModifyCatchRate.add(:SCORCHBALL,proc{|ball,catchRate,battle,battler|
# battler.status = :BURN
# next catchRate
# })
# #FROSTBALL - frozen
# BallHandlers::ModifyCatchRate.add(:FROSTBALL,proc{|ball,catchRate,battle,battler|
# battler.status = :FROZEN
# next catchRate
# })
# #SPARKBALL - paralizé
# BallHandlers::ModifyCatchRate.add(:SPARKBALL,proc{|ball,catchRate,battle,battler|
# battler.status = :PARALYSIS
# next catchRate
# })
# #PUREBALL - marche mieux quand pas de status
# BallHandlers::ModifyCatchRate.add(:PUREBALL,proc{|ball,catchRate,battle,battler|
# catchRate=(catchRate*7/2).floor if battler.status ==0
# next catchRate
# })
# #STATUSBALL - marche mieux quand any status
# BallHandlers::ModifyCatchRate.add(:STATUSBALL,proc{|ball,catchRate,battle,battler|
# catchRate=(catchRate*5/2).floor if battler.status !=0
# next catchRate
# })
#
# #FUSIONBALL - marche mieux quand fusedr
# BallHandlers::ModifyCatchRate.add(:FUSIONBALL,proc{|ball,catchRate,battle,battler|
# catchRate*=3 if GameData::Species.get(battler.species).id_number > Settings::NB_POKEMON
# next catchRate
# })
#
# #CANDY BALL - +5 level
# #catchrate: 80% pokeball
# BallHandlers::ModifyCatchRate.add(:CANDYBALL,proc{|ball,catchRate,battle,pokemon|
# catchRate=(catchRate*0.8).floor
# next catchRate
# })
# BallHandlers::OnCatch.add(:CANDYBALL,proc{|ball,battle,pokemon|
# pokemon.level = pokemon.level+5
# })
# #FIRECRACKER
# BallHandlers::ModifyCatchRate.add(:FIRECRACKER,proc{|ball,catchRate,battle,battler|
# battler.hp -= 10
# next 0
# })

View File

@@ -0,0 +1,141 @@
#===============================================================================
# Rock Smash
#===============================================================================
def pbRockSmashRandomEncounter
if rand(100)<30
if pbEncounter(:RockSmash)
return
else
pbDefaultRockSmashEncounter(5,15)
end
else
rockSmashItem(false)
end
end
def pbDefaultRockSmashEncounter(minLevel,maxLevel)
level =rand((maxLevel-minLevel).abs)+minLevel
pbWildBattle(:GEODUDE,level)
return true
end
#FOR ROCK TUNNEL AND CERULEAN CAVE (+diamond)
def pbRockSmashRandomEncounterSpecial
if rand(100)<35
pbEncounter(:RockSmash)
else
rockSmashItem(true)
end
end
def getRockSmashItemList(inclRareItems)
basicItems = [:ROCKGEM, :GROUNDGEM,:STEELGEM,
:HARDSTONE,:HARDSTONE,:HARDSTONE,:ROCKGEM,
:SMOOTHROCK,:STARDUST,:HEARTSCALE,:HEARTSCALE,
:HEARTSCALE,:SOFTSAND,:HEARTSCALE,:RAREBONE]
rareItems = [:RAREBONE,:STARDUST,:ETHER,
:REVIVE,:NUGGET,:DIAMOND]
fossilItems = [:ROOTFOSSIL,:CLAWFOSSIL,:DOMEFOSSIL,:HELIXFOSSIL,
:SKULLFOSSIL,:ARMORFOSSIL,:JAWFOSSIL,:SAILFOSSIL]
# Kernel.pbMessage(inclRareItems.to_s)
itemsList = inclRareItems ? basicItems + basicItems + rareItems : basicItems
#beaten league
if $game_switches[12]
itemsList += fossilItems
end
return itemsList
end
def rockSmashItem(isDark=false)
chance = 50
if rand(100)< chance
if rand(5) == 0 && !hatUnlocked?(HAT_AERODACTYL)
obtainHat(HAT_AERODACTYL)
else
itemsList = getRockSmashItemList(isDark)
i = rand(itemsList.length)
Kernel.pbItemBall(itemsList[i],1,nil,false)
end
end
end
#Used in underwater maps
def pbRockSmashRandomEncounterDive
if rand(100)<25
pbEncounter(:RockSmash)
else
if rand(100)<20
itemsList = [:WATERGEM,:STEELGEM,
:HEARTSCALE,:HEARTSCALE,:HARDSTONE,:ROCKGEM,
:SMOOTHROCK,:WATERSTONE,:PEARL,:HEARTSCALE,
:HEARTSCALE,:HEARTSCALE,:SHOALSHELL,:BIGPEARL]
i = rand(itemsList.length)
Kernel.pbItemBall(itemsList[i],1,nil,false)
end
end
end
############### MORNING SUN / MOONLIGHT
HiddenMoveHandlers::CanUseMove.add(:MORNINGSUN,proc{|move,pkmn|
mapMetadata = GameData::MapMetadata.try_get($game_map.map_id)
if !mapMetadata || !mapMetadata.outdoor_map
Kernel.pbMessage(_INTL("Can't use that here."))
next false
end
next true
})
HiddenMoveHandlers::UseMove.add(:MORNINGSUN,proc{|move,pokemon|
Kernel.pbMessage(_INTL("{1} used {2}!",pokemon.name,GameData::Move.get(move).name))
pbHiddenMoveAnimation(pokemon)
pbFadeOutIn(99999){
pbSkipTime(9)
newTime = pbGetTimeNow.strftime("%I:%M %p")
Kernel.pbMessage(_INTL("{1} waited until morning...",$player.name))
Kernel.pbMessage(_INTL("The time is now {1}",newTime))
$game_screen.weather(:None,0,0)
$game_map.refresh
}
next true
})
HiddenMoveHandlers::CanUseMove.add(:MOONLIGHT,proc{|move,pkmn|
mapMetadata = GameData::MapMetadata.try_get($game_map.map_id)
if !mapMetadata || !mapMetadata.outdoor_map
Kernel.pbMessage(_INTL("Can't use that here."))
next false
end
next true
})
HiddenMoveHandlers::UseMove.add(:MOONLIGHT,proc{|move,pokemon|
Kernel.pbMessage(_INTL("{1} used {2}!",pokemon.name,GameData::Move.get(move).name))
pbHiddenMoveAnimation(pokemon)
pbFadeOutIn(99999){
pbSkipTime(21)
newTime = pbGetTimeNow.strftime("%I:%M %p")
Kernel.pbMessage(_INTL("{1} waited until night...",$player.name))
Kernel.pbMessage(_INTL("The time is now {1}",newTime))
$game_screen.weather(:None,0,0)
$game_map.refresh
}
next true
})
def pbSkipTime(newTime)
currentTime = pbGetTimeNow.hour
hoursToAdd = newTime - currentTime
$game_variables[UnrealTime::EXTRA_SECONDS] += hoursToAdd*3600
end

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,409 @@
def find_last_outfit(outfit_type_path, firstOutfit)
for i in firstOutfit..Settings::MAX_NB_OUTFITS
outfit_path = outfit_type_path + "/" + i.to_s #Settings::PLAYER_GRAPHICS_FOLDER + outfit_type_path + "/" + outfit_type_path + "_" + player_sprite + "_" + i.to_s
return i - 1 if !Dir.exist?(outfit_path)
end
return firstOutfit
end
def list_all_numeric_folders(directory_path)
entries = Dir.entries(directory_path)
# Filter out only the directories whose names are numeric (excluding "." and "..")
numeric_folders = entries.select do |entry|
full_path = File.join(directory_path, entry)
File.directory?(full_path) && entry != '.' && entry != '..' && entry.match?(/^\d+$/)
end
# Convert the folder names to integers and store in an array
folder_integers = numeric_folders.map(&:to_i)
folder_integers.sort!
return folder_integers
end
def list_all_numeric_files_with_filter(directory_path, prefix)
entries = Dir.entries(directory_path)
prefixless = []
for file in entries
next if file == "." || file == ".."
prefixless << file.gsub((prefix + "_"), "")
end
folder_integers = prefixless.map(&:to_i)
folder_integers.sort!
return folder_integers
end
#unlocked:
# -1 for all outfits unlocked
# Otherwise, an array of the ids of unlocked outfits
def list_available_outfits(directory, versions = [], unlocked = [], prefix_filter = nil)
if prefix_filter
outfits = list_all_numeric_files_with_filter(directory, prefix_filter)
else
outfits = list_all_numeric_folders(directory)
end
# #echoln outfits
# return outfits #todo: remove this return for unlockable outfits
available_outfits = []
for outfit in outfits
if !unlocked || unlocked.include?(outfit)
for version in versions
available_outfits << outfit.to_s + version
end
available_outfits << outfit.to_s if versions.empty?
end
end
return available_outfits
end
def get_current_outfit_position(currentOutfit_id, available_outfits)
current_index = available_outfits.index(currentOutfit_id)
return current_index.nil? ? 0 : current_index
end
def setHairColor(hue_shift)
$player.hair_color = hue_shift
refreshPlayerOutfit()
end
def shiftHatColor(incr,secondary_hat=false)
if secondary_hat
$player.hat2_color = 0 if !$player.hat2_color
$player.hat2_color += incr
else
$player.hat_color = 0 if !$player.hat_color
$player.hat_color += incr
end
refreshPlayerOutfit()
end
def shiftClothesColor(incr)
$player.clothes_color = 0 if !$player.clothes_color
$player.clothes_color += incr
refreshPlayerOutfit()
end
def shiftHairColor(incr)
$player.hair_color = 0 if !$player.hair_color
$player.hair_color += incr
echoln "Hair color: #{$player.hair_color}"
refreshPlayerOutfit()
end
def pbLoadOutfitBitmap(outfitFileName)
begin
outfitBitmap = RPG::Cache.load_bitmap("", outfitFileName)
return outfitBitmap
rescue
return nil
end
end
def setOutfit(outfit_id)
$player.clothes = outfit_id
end
def setHat(hat_id)
$player.hat = hat_id
end
def getEasterEggHeldItem()
map = $game_map.map_id
return "secrets/HOTDOG" if [141, 194].include?(map) #restaurant
return "secrets/SNOWBALL" if [670, 693, 698, 694].include?(map)
return "secrets/WALLET" if [432, 433, 434, 435, 436, 292].include?(map) #dept. store
return "secrets/ALARMCLOCK" if [43, 48, 67, 68, 69, 70, 71, 73].include?(map) #Overrides room
return "SAFARIBALL" if [445, 484, 485, 486, 107, 487, 488, 717, 82, 75, 74].include?(map) #Safari Zone
return "secrets/WISP" if [401,402,403,467,468,469].include?(map) #Pokemon Tower
return "secrets/SKULL" if [400].include?(map) #Pokemon Tower ground floor
return "secrets/ROCK" if [349,350,800,].include?(map) #Rock Tunnel
return "secrets/MAGIKARP" if [394,471,189,].include?(map) #Fishing huts
return "secrets/AZUREFLUTE" if [694,].include?(map) && $PokemonBag.pbQuantity(:AZUREFLUTE)>=1 #Ice Mountain peak
return "secrets/BIGSODA" if [436,].include?(map) && $PokemonBag.pbQuantity(:SODAPOP)>=1 #Celadon dept. store top
return "secrets/EGG" if [13,406,214,].include?(map) #Day care
return "secrets/STICK" if [266,].include?(map) #Ilex forest
return "secrets/BANANA" if [600,].include?(map) #Bond Bridge
return "secrets/BERRY" if [619,620,].include?(map) #Berry forest
return "secrets/COIN" if [357].include?(map) #Pokemart
return "secrets/LATTE" if [406].include?(map) #Celadon Café
return nil
end
def getCurrentPokeball(allowEasterEgg=true)
otherItem = getEasterEggHeldItem() if allowEasterEgg
return otherItem if otherItem
firstPokemon = $player.party[0]
return firstPokemon.poke_ball if firstPokemon
return nil
end
def generate_front_trainer_sprite_bitmap_from_appearance(trainerAppearance)
echoln trainerAppearance.hat
return generate_front_trainer_sprite_bitmap(false,nil,trainerAppearance.clothes,trainerAppearance.hat,trainerAppearance.hat2,
trainerAppearance.hair,trainerAppearance.skin_color,
trainerAppearance.hair_color,trainerAppearance.hat_color,trainerAppearance.clothes_color,
trainerAppearance.hat2_color)
end
def generate_front_trainer_sprite_bitmap(allowEasterEgg=true, pokeball = nil,
clothes_id = nil, hat_id = nil, hat2_id=nil, hair_id = nil,
skin_tone_id = nil, hair_color = nil, hat_color = nil, clothes_color = nil,
hat2_color = nil)
clothes_id = $player.clothes if !clothes_id
hat_id = $player.hat if !hat_id
hat2_id = $player.hat2 if !hat2_id
hair_id = $player.hair if !hair_id
skin_tone_id = $player.skin_tone if !skin_tone_id
hair_color = $player.hair_color if !hair_color
hat_color = $player.hat_color if !hat_color
hat2_color = $player.hat2_color if !hat2_color
clothes_color = $player.clothes_color if !clothes_color
hairFilename = getTrainerSpriteHairFilename(hair_id) #_INTL(Settings::PLAYER_GRAPHICS_FOLDER + Settings::PLAYER_HAIR_FOLDER + "/hair_trainer_{1}", $player.hair)
outfitFilename = getTrainerSpriteOutfitFilename(clothes_id) #_INTL(Settings::PLAYER_GRAPHICS_FOLDER + Settings::PLAYER_CLOTHES_FOLDER + "/clothes_trainer_{1}", $player.clothes)
hatFilename = getTrainerSpriteHatFilename(hat_id)
hat2Filename = getTrainerSpriteHatFilename(hat2_id)
pokeball = getCurrentPokeball(allowEasterEgg) if !pokeball
ballFilename = getTrainerSpriteBallFilename(pokeball) if pokeball
baseFilePath = getBaseTrainerSpriteFilename(skin_tone_id)
hair_color_shift = hair_color
hat_color_shift = hat_color
hat2_color_shift = hat2_color
clothes_color_shift = clothes_color
hair_color_shift = 0 if !hair_color_shift
hat_color_shift = 0 if !hat_color_shift
hat2_color_shift = 0 if !hat2_color_shift
clothes_color_shift = 0 if !clothes_color_shift
baseBitmap = AnimatedBitmap.new(baseFilePath) if pbResolveBitmap(baseFilePath)
ballBitmap = pbLoadOutfitBitmap(ballFilename) if pbResolveBitmap(ballFilename)
if !pbResolveBitmap(outfitFilename)
outfitFilename = getTrainerSpriteOutfitFilename(Settings::PLAYER_TEMP_OUTFIT_FALLBACK)
end
if !pbResolveBitmap(outfitFilename)
raise "No temp clothes graphics available"
end
outfitBitmap = AnimatedBitmap.new(outfitFilename, clothes_color_shift) if pbResolveBitmap(outfitFilename) #pb
hairBitmapWrapper = AnimatedBitmap.new(hairFilename, hair_color_shift) if pbResolveBitmap(hairFilename)
hatBitmap = AnimatedBitmap.new(hatFilename, hat_color_shift) if pbResolveBitmap(hatFilename)
hat2Bitmap = AnimatedBitmap.new(hat2Filename, hat2_color_shift) if pbResolveBitmap(hat2Filename)
baseBitmap.bitmap = baseBitmap.bitmap.clone
if outfitBitmap
baseBitmap.bitmap.blt(0, 0, outfitBitmap.bitmap, outfitBitmap.bitmap.rect)
else
outfitFilename = getTrainerSpriteOutfitFilename("temp")
outfitBitmap = AnimatedBitmap.new(outfitFilename, 0)
baseBitmap.bitmap.blt(0, 0, outfitBitmap.bitmap, outfitBitmap.bitmap.rect)
end
baseBitmap.bitmap.blt(0, 0, hairBitmapWrapper.bitmap, hairBitmapWrapper.bitmap.rect) if hairBitmapWrapper
baseBitmap.bitmap.blt(0, 0, hat2Bitmap.bitmap, hat2Bitmap.bitmap.rect) if hat2Bitmap
baseBitmap.bitmap.blt(0, 0, hatBitmap.bitmap, hatBitmap.bitmap.rect) if hatBitmap
baseBitmap.bitmap.blt(44, 42, ballBitmap, ballBitmap.rect) if ballBitmap
return baseBitmap
end
def generateNPCClothedBitmapStatic(trainerAppearance,action = "walk")
baseBitmapFilename = getBaseOverworldSpriteFilename(action, trainerAppearance.skin_color)
baseSprite = AnimatedBitmap.new(baseBitmapFilename)
baseBitmap = baseSprite.bitmap.clone # nekkid sprite
outfitFilename = getOverworldOutfitFilename(trainerAppearance.clothes, action)
hairFilename = getOverworldHairFilename(trainerAppearance.hair)
#Clothes
clothes_color_shift = trainerAppearance.clothes_color || 0
clothesBitmap = AnimatedBitmap.new(outfitFilename, clothes_color_shift).bitmap if pbResolveBitmap(outfitFilename)
baseBitmap.blt(0, 0, clothesBitmap, clothesBitmap.rect)
#clothesBitmap.dispose
#Hair
hair_color_shift = trainerAppearance.hair_color || 0
hairBitmap = AnimatedBitmap.new(hairFilename, hair_color_shift).bitmap if pbResolveBitmap(hairFilename)
baseBitmap.blt(0, 0, hairBitmap, hairBitmap.rect)
#Hat
hat_color_shift = trainerAppearance.hat_color || 0
hat2_color_shift = trainerAppearance.hat2_color || 0
hatFilename = getOverworldHatFilename(trainerAppearance.hat)
hat2Filename = getOverworldHatFilename(trainerAppearance.hat2)
hatBitmapWrapper = AnimatedBitmap.new(hatFilename, hat_color_shift) if pbResolveBitmap(hatFilename)
hat2BitmapWrapper = AnimatedBitmap.new(hat2Filename, hat2_color_shift) if pbResolveBitmap(hat2Filename)
if hat2BitmapWrapper
frame_count = 4 # Assuming 4 frames for hair animation; adjust as needed
hat2_frame_bitmap = duplicateHatForFrames(hat2BitmapWrapper.bitmap, frame_count)
frame_width = baseSprite.bitmap.width / frame_count # Calculate frame width
frame_count.times do |i|
# Calculate offset for each frame
frame_offset = [i * frame_width, 0]
# Adjust Y offset if frame index is odd
frame_offset[1] -= 2 if i.odd?
positionHat(baseBitmap, hat2_frame_bitmap, frame_offset, i, frame_width)
end
end
if hatBitmapWrapper
frame_count = 4 # Assuming 4 frames for hair animation; adjust as needed
hat_frame_bitmap = duplicateHatForFrames(hatBitmapWrapper.bitmap, frame_count)
frame_width = baseSprite.bitmap.width / frame_count # Calculate frame width
frame_count.times do |i|
# Calculate offset for each frame
frame_offset = [i * frame_width, 0]
# Adjust Y offset if frame index is odd
frame_offset[1] -= 2 if i.odd?
positionHat(baseBitmap, hat_frame_bitmap, frame_offset, i, frame_width)
end
end
return baseBitmap
end
#for continue screen
def generateClothedBitmapStatic(trainer, action = "walk")
baseBitmapFilename = getBaseOverworldSpriteFilename(action, trainer.skin_tone)
if !pbResolveBitmap(baseBitmapFilename)
baseBitmapFilename = Settings::PLAYER_GRAPHICS_FOLDER + action
end
baseSprite = AnimatedBitmap.new(baseBitmapFilename)
# Clone the base sprite bitmap to create the base for the player's sprite
baseBitmap = baseSprite.bitmap.clone # nekkid sprite
outfitFilename = getOverworldOutfitFilename(trainer.clothes, action)
outfitFilename = getOverworldOutfitFilename(Settings::PLAYER_TEMP_OUTFIT_FALLBACK) if !pbResolveBitmap(outfitFilename)
hairFilename = getOverworldHairFilename(trainer.hair)
hatFilename = getOverworldHatFilename(trainer.hat)
hat2Filename = getOverworldHatFilename(trainer.hat2)
# Use default values if color shifts are not set
hair_color_shift = trainer.hair_color || 0
hat_color_shift = trainer.hat_color || 0
hat2_color_shift = trainer.hat2_color || 0
clothes_color_shift = trainer.clothes_color || 0
# Use fallback outfit if the specified outfit cannot be resolved
if !pbResolveBitmap(outfitFilename)
outfitFilename = Settings::PLAYER_TEMP_OUTFIT_FALLBACK
end
# Load the outfit and hair bitmaps
outfitBitmap = AnimatedBitmap.new(outfitFilename, clothes_color_shift)
hairBitmapWrapper = AnimatedBitmap.new(hairFilename, hair_color_shift) if pbResolveBitmap(hairFilename)
hatBitmapWrapper = AnimatedBitmap.new(hatFilename, hat_color_shift) if pbResolveBitmap(hatFilename)
hat2BitmapWrapper = AnimatedBitmap.new(hat2Filename, hat2_color_shift) if pbResolveBitmap(hat2Filename)
# Blit the outfit onto the base sprite
baseBitmap.blt(0, 0, outfitBitmap.bitmap, outfitBitmap.bitmap.rect) if outfitBitmap
current_offset = [0, 0] # Replace this with getCurrentSpriteOffset() if needed
positionHair(baseBitmap, hairBitmapWrapper.bitmap, current_offset) if hairBitmapWrapper
frame_count = 4
frame_width = baseSprite.bitmap.width / frame_count # Calculate frame width
if hat2BitmapWrapper
hat2_frame_bitmap = duplicateHatForFrames(hat2BitmapWrapper.bitmap, frame_count)
frame_count.times do |i|
# Calculate offset for each frame
frame_offset = [i * frame_width, 0]
# Adjust Y offset if frame index is odd
frame_offset[1] -= 2 if i.odd?
positionHat(baseBitmap, hat2_frame_bitmap, frame_offset, i, frame_width)
end
end
if hatBitmapWrapper
hat_frame_bitmap = duplicateHatForFrames(hatBitmapWrapper.bitmap, frame_count)
frame_count.times do |i|
# Calculate offset for each frame
frame_offset = [i * frame_width, 0]
# Adjust Y offset if frame index is odd
frame_offset[1] -= 2 if i.odd?
positionHat(baseBitmap, hat_frame_bitmap, frame_offset, i, frame_width)
end
end
return baseBitmap
end
def positionHair(baseBitmap, hairBitmap, offset)
baseBitmap.blt(offset[0], offset[1], hairBitmap, hairBitmap.rect)
end
def positionHat(baseBitmap, hatBitmap, offset, frame_index, frame_width)
# Define a rect for each frame
frame_rect = Rect.new(frame_index * frame_width, 0, frame_width, hatBitmap.height)
# Blit only the part of the hat corresponding to the current frame
baseBitmap.blt(offset[0], offset[1], hatBitmap, frame_rect)
end
def duplicateHatForFrames(hatBitmap, frame_count)
# Create a new bitmap for the duplicated hat frames
frame_width = hatBitmap.width
total_width = frame_width * frame_count
duplicatedBitmap = Bitmap.new(total_width, hatBitmap.height)
# Copy the single hat frame across each required frame
frame_count.times do |i|
duplicatedBitmap.blt(i * frame_width, 0, hatBitmap, hatBitmap.rect)
end
return duplicatedBitmap
end
def add_hat_to_bitmap(bitmap, hat_id, x_pos, y_pos, scale = 1, mirrored = false)
base_scale = 1.5 #coz hat & poke sprites aren't the same size
adjusted_scale = base_scale * scale
hat_filename = getTrainerSpriteHatFilename(hat_id)
hatBitmapWrapper = AnimatedBitmap.new(hat_filename, 0) if pbResolveBitmap(hat_filename)
hatBitmapWrapper.scale_bitmap(adjusted_scale) if hatBitmapWrapper
hatBitmapWrapper.mirror if hatBitmapWrapper && mirrored
bitmap.blt(x_pos * adjusted_scale, y_pos * adjusted_scale, hatBitmapWrapper.bitmap, hatBitmapWrapper.bitmap.rect) if hatBitmapWrapper
end
class PokemonTemp
attr_accessor :trainer_preview
end
def display_outfit_preview(x = 320, y = 0, withBorder = true)
hide_outfit_preview() if $PokemonTemp.trainer_preview
$PokemonTemp.trainer_preview = TrainerClothesPreview.new(x, y, withBorder)
$PokemonTemp.trainer_preview.show()
end
def hide_outfit_preview()
$game_screen.pictures[20].erase
$PokemonTemp.trainer_preview.erase() if $PokemonTemp.trainer_preview
$PokemonTemp.trainer_preview = nil
end

View File

@@ -0,0 +1,174 @@
class OutfitSelector
attr_reader :clothes_list
attr_reader :hats_list
attr_reader :hairstyles_list
def initialize()
@clothes_list = parse_clothes_folder()
@hats_list = parse_hats_folder()
@hairstyles_list =parse_hairstyles_folder()
end
def parse_clothes_folder
return list_folders(get_clothes_sets_list_path())
end
def parse_hats_folder
return list_folders(get_hats_sets_list_path())
end
def parse_hairstyle_types_folder
return list_folders(get_hair_sets_list_path())
end
def generate_hats_choice(baseOptions=true,additionalIds=[],additionalTags=[],filterOutTags=[])
list = []
list += additionalIds
list += search_hats(additionalTags)
if baseOptions
list += get_hats_base_options()
list += search_hats(get_regional_sets_tags())
end
return list
end
def generate_clothes_choice(baseOptions=true,additionalIds=[],additionalTags=[],filterOutTags=[])
list = []
list += additionalIds
list += search_clothes(additionalTags)
if baseOptions
list += get_clothes_base_options()
list += search_clothes(get_regional_sets_tags())
end
return list
end
def generate_hairstyle_choice(baseOptions=true,additionalIds=[],additionalTags=[],filterOutTags=[])
list = []
list += additionalIds
list += search_hairstyles(additionalTags)
if baseOptions
list += get_hairstyle_salon_base_options()
list += search_hairstyles(get_regional_sets_tags())
end
list << HAIR_BALD
return list
end
def get_regional_sets_tags()
regional_tags = []
regional_tags << "kanto" if $game_switches[SWITCH_KANTO_HAIR_COLLECTION]
regional_tags << "johto" if $game_switches[SWITCH_JOHTO_HAIR_COLLECTION]
regional_tags << "hoenn" if $game_switches[SWITCH_HOENN_HAIR_COLLECTION]
regional_tags << "sinnoh" if $game_switches[SWITCH_SINNOH_HAIR_COLLECTION]
regional_tags << "unova" if $game_switches[SWITCH_UNOVA_HAIR_COLLECTION]
regional_tags << "kalos" if $game_switches[SWITCH_KALOS_HAIR_COLLECTION]
regional_tags << "alola" if $game_switches[SWITCH_ALOLA_HAIR_COLLECTION]
regional_tags << "galar" if $game_switches[SWITCH_GALAR_HAIR_COLLECTION]
regional_tags << "paldea" if $game_switches[SWITCH_PALDEA_HAIR_COLLECTION]
return regional_tags
end
def get_hairstyle_salon_base_options()
return search_hairstyles(["default"])
end
def get_clothes_base_options()
return search_clothes(["default"])
end
def get_hats_base_options()
return search_hats(["default"])
end
def parse_hairstyles_folder
hairstyle_types= list_folders(get_hair_sets_list_path())
max_versions_number = 10
list= []
for hairstyle in hairstyle_types
for i in 1..max_versions_number
type = i.to_s + "_" + hairstyle
filePath = getOverworldHairFilename(type)
if pbResolveBitmap(filePath)
list << type
end
end
end
return list
end
def list_folders(path)
entries= Dir.entries(path)
return entries.select { |entry| File.directory?(File.join(path, entry)) && entry != '.' && entry != '..' }
end
def filter_unlocked_outfits(outfits_list,unlocked_outfits)
available_outfits = []
outfits_list.each do |outfit|
available_outfits << outfit if unlocked_outfits.include?(outfit)
end
return available_outfits
end
def selectNextOutfit(currentOutfit, incr, outfits_list, versions = [], allowNone = true, prefix_filter = nil,unlockedOutfits=[],everythingUnlocked=false)
available_outfits = []
available_outfits = outfits_list if everythingUnlocked
available_outfits << "" if allowNone
available_outfits += filter_unlocked_outfits(outfits_list,unlockedOutfits) if !everythingUnlocked
#available_outfits += list_available_outfits(directory, versions, unlockedOutfits, prefix_filter) #unlockedOutfits = nil for all outfits unlocked
last_outfit = available_outfits[-1]
current_outfit_index = get_current_outfit_position(currentOutfit, available_outfits)
next_outfit_index = current_outfit_index +incr
nextOutfit = available_outfits[next_outfit_index]
nextOutfit = last_outfit if next_outfit_index < 0
nextOutfit = available_outfits[0] if next_outfit_index >= available_outfits.length()
return nextOutfit if available_outfits.include?(nextOutfit)
return currentOutfit
end
def changeToNextClothes(incr,all_unlocked=false)
$player.unlocked_clothes = [] if !$player.unlocked_clothes
currentOutfit = $player.clothes
currentOutfit = 0 if !currentOutfit
nextOutfit = selectNextOutfit(currentOutfit, incr, @clothes_list, [], false,nil,$player.unlocked_clothes,all_unlocked)
$player.clothes = nextOutfit
$player.clothes_color = 0
echoln $player.clothes
end
def changeToNextHat(incr,all_unlocked=false)
$player.unlocked_hats = [] if !$player.unlocked_hats
currentHat = $player.hat
currentHat = 0 if !currentHat
nextOutfit = selectNextOutfit(currentHat, incr, @hats_list, [], true, "hat",$player.unlocked_hats,all_unlocked)
$player.hat = nextOutfit
$player.hat_color = 0
echoln $player.hat
end
def changeToNextHairstyle(incr,all_unlocked=false)
$player.unlocked_hairstyles = [] if !$player.unlocked_hairstyles
currentHair = $player.hair
currentHair = 0 if !currentHair
nextOutfit = selectNextOutfit(currentHair, incr, @hairstyles_list, ["a", "b", "c", "d"], true,nil,$player.unlocked_hairstyles,all_unlocked)
$player.hair_color = 0
$player.hair = nextOutfit
echoln $player.hair
end
end

View File

@@ -0,0 +1,75 @@
class PokemonGlobalMetadata
attr_accessor :hats_data
attr_accessor :hairstyles_data
attr_accessor :clothes_data
end
def update_global_hats_list()
file_path = Settings::HATS_DATA_PATH
json_data = File.read(file_path)
hat_data = HTTPLite::JSON.parse(json_data)
$PokemonGlobal.hats_data = {}
# Iterate through the JSON data and create Hat objects
hat_data.each do |data|
tags = data['tags'] ? data['tags'].split(',').map(&:strip) : []
hat = Hat.new(
data['id'],
data['name'],
data['description'],
data['price'],
tags
)
$PokemonGlobal.hats_data[hat.id] = hat
end
end
def update_global_hairstyles_list()
file_path = Settings::HAIRSTYLE_DATA_PATH
json_data = File.read(file_path)
hair_data = HTTPLite::JSON.parse(json_data)
$PokemonGlobal.hairstyles_data = {}
# Iterate through the JSON data and create Hat objects
hair_data.each do |data|
tags = data['tags'] ? data['tags'].split(',').map(&:strip) : []
hair = Hairstyle.new(
data['id'],
data['name'],
data['description'],
data['price'],
tags
)
$PokemonGlobal.hairstyles_data[hair.id] = hair
end
end
def update_global_clothes_list()
file_path = Settings::CLOTHES_DATA_PATH
json_data = File.read(file_path)
outfits_data = HTTPLite::JSON.parse(json_data)
$PokemonGlobal.clothes_data = {}
# Iterate through the JSON data and create Hat objects
outfits_data.each do |data|
tags = data['tags'] ? data['tags'].split(',').map(&:strip) : []
outfit = Clothes.new(
data['id'],
data['name'],
data['description'],
data['price'],
tags
)
$PokemonGlobal.clothes_data[outfit.id] = outfit
end
end
def update_global_outfit_lists()
update_global_hats_list
update_global_hairstyles_list
update_global_clothes_list
end

View File

@@ -0,0 +1,221 @@
#CLOTHES
def search_clothes(matching_tags = [], only_unlocked = false)
update_global_outfit_lists()
selector = OutfitSelector.new
full_data_list = $PokemonGlobal.clothes_data
existing_files_list = selector.parse_clothes_folder()
unlocked_list = $player.unlocked_clothes
return search_outfits_by_tag(full_data_list, matching_tags, existing_files_list, unlocked_list, only_unlocked)
end
def filter_clothes(filter_tags = [], only_unlocked = false)
update_global_outfit_lists()
selector = OutfitSelector.new
full_data_list = $PokemonGlobal.hats_data
existing_files_list = selector.parse_hats_folder()
unlocked_list = $player.unlocked_hats
return filter_outfits_by_tag(full_data_list, filter_tags, existing_files_list, unlocked_list, only_unlocked)
end
def filter_clothes_only_not_owned(clothes_ids_list)
filtered_list = []
clothes_ids_list.each do|clothe_id|
filtered_list << clothe_id if !$player.unlocked_clothes.include?(clothe_id)
end
return filtered_list
end
def filter_clothes_only_owned(clothes_ids_list)
filtered_list = []
clothes_ids_list.each do|clothe_id|
filtered_list << clothe_id if $player.unlocked_clothes.include?(clothe_id)
end
return filtered_list
end
#HATS
def search_hats(matching_tags = [],excluding_tags=[], only_unlocked = false)
update_global_outfit_lists()
selector = OutfitSelector.new
full_data_list = $PokemonGlobal.hats_data
existing_files_list = selector.parse_hats_folder()
unlocked_list = $player.unlocked_hats
return search_outfits_by_tag(full_data_list, matching_tags, existing_files_list, unlocked_list, only_unlocked,excluding_tags)
end
def filter_hats(filter_tags = [], only_unlocked = false)
update_global_outfit_lists()
selector = OutfitSelector.new
full_data_list = $PokemonGlobal.hats_data
existing_files_list = selector.parse_hats_folder()
unlocked_list = $player.unlocked_hats
return filter_outfits_by_tag(full_data_list, filter_tags, existing_files_list, unlocked_list, only_unlocked)
end
def filter_hats_only_not_owned(hats_ids_list)
filtered_list = []
hats_ids_list.each do|hat_id|
filtered_list << hat_id if !$player.unlocked_hats.include?(hat_id)
end
return filtered_list
end
def filter_hats_only_owned(hats_ids_list)
filtered_list = []
hats_ids_list.each do|hat_id|
filtered_list << hat_id if $player.unlocked_hats.include?(hat_id)
end
return filtered_list
end
#HAIRSTYLES
def search_hairstyles(matching_tags = [], only_unlocked = false)
update_global_outfit_lists()
selector = OutfitSelector.new
full_data_list = $PokemonGlobal.hairstyles_data
existing_files_list = selector.parse_hairstyle_types_folder()
return search_outfits_by_tag(full_data_list, matching_tags, existing_files_list, [], false)
end
def filter_out_hairstyles(filter_tags = [],base_list = [],require_unlocked=false)
update_global_outfit_lists()
selector = OutfitSelector.new
data_list = $PokemonGlobal.hairstyles_data
existing_files_list = selector.parse_hairstyle_types_folder()
return exclude_outfits_by_tag(data_list, filter_tags, existing_files_list, base_list, false)
end
# Generic searching methods
#Get outfits that have ANY of the tags
def search_outfits_by_tag(outfits_map, matching_tags = [], physical_files_list = [], unlocked_list = [], require_unlocked = false, excluding_tags=[])
filtered_list = []
outfits_map.each do |outfit_id, outfit|
next if outfit.tags.any? { |tag| excluding_tags.include?(tag) }
if outfit.tags.any? { |tag| matching_tags.include?(tag) }
filtered_list << outfit_id if outfit_is_valid?(outfit_id, physical_files_list, unlocked_list, require_unlocked)
end
end
return filtered_list
end
#Get outfits that have ALL of the tags
def filter_outfits_by_tag(outfits_map, filter_tags = [], physical_files_list = [], unlocked_list = [], require_unlocked = false)
update_global_outfit_lists()
filtered_list = []
outfits_map.each do |outfit_id, outfit|
if filter_tags.all? { |tag| outfit.tags.include?(tag) }
filtered_list << outfit_id if outfit_is_valid?(outfit_id, physical_files_list, unlocked_list, require_unlocked)
end
end
return filtered_list
end
#Get all outfits from list that DON'T have a tag
def exclude_outfits_by_tag(outfits_map, filter_tags = [], physical_files_list = [], unlocked_list = [], require_unlocked = false)
update_global_outfit_lists()
filtered_list = []
outfits_map.each do |outfit_id, outfit|
if filter_tags.any? { |tag| !outfit.tags.include?(tag) }
filtered_list << outfit_id if outfit_is_valid?(outfit_id, physical_files_list, unlocked_list, require_unlocked)
end
end
return filtered_list
end
def outfit_is_valid?(outfit_id, physical_files_list, unlocked_list, require_unlocked)
return false if require_unlocked && !unlocked_list.include?(outfit_id)
return physical_files_list.include?(outfit_id)
end
def add_tags(tags_list=[])
newTag=pbEnterText("add tag",0,10)
return tags_list if newTag.length == 0
tags_list << newTag
return tags_list
end
def get_clothes_by_id(id)
update_global_outfit_lists()
return $PokemonGlobal.clothes_data.has_key?(id) ? $PokemonGlobal.clothes_data[id] : nil
end
def get_hat_by_id(id)
update_global_outfit_lists()
return $PokemonGlobal.hats_data.has_key?(id) ? $PokemonGlobal.hats_data[id] : nil
end
def get_hair_by_id(id)
update_global_outfit_lists()
return $PokemonGlobal.hairstyles_data.has_key?(id) ? $PokemonGlobal.hairstyles_data[id] : nil
end
def generate_clothes_choice(baseOptions=true,additionalIds=[],additionalTags=[],filterOutTags=[])
list = []
list += additionalIds
list += search_clothes(additionalTags)
if baseOptions
list += get_clothes_base_options()
list += search_clothes(get_regional_sets_tags())
end
return list
end
CITY_OUTFIT_TAGS= [
"pewter","cerulean","vermillion","lavender","celadon","fuchsia","cinnabar",
"crimson","goldenrod","azalea", "violet", "blackthorn", "mahogany", "ecruteak",
"olivine","cianwood", "kin"
]
def list_city_exclusive_clothes()
tags_list = CITY_OUTFIT_TAGS
echoln search_clothes(tags_list)
return search_clothes(tags_list)
end
def list_city_exclusive_hats()
tags_list = CITY_OUTFIT_TAGS
return search_hats(tags_list)
end
def list_city_exclusive_hairstyles()
tags_list = CITY_OUTFIT_TAGS
return search_hairstyles(tags_list)
end
def list_regional_clothes()
selector = OutfitSelector.new
tags_list = selector.get_regional_sets_tags()
return search_clothes(tags_list)
end
def list_regional_hats()
selector = OutfitSelector.new
tags_list = selector.get_regional_sets_tags()
return search_hats(tags_list)
end
def list_regional_hairstyles()
selector = OutfitSelector.new
tags_list = selector.get_regional_sets_tags()
return search_hairstyles(tags_list)
end

View File

@@ -0,0 +1,185 @@
#set outfit ids,
#
CLOTHES_NORMAL = "normal"
CLOTHES_FIGHTING = "fighting"
CLOTHES_FLYING = "temp"
CLOTHES_POISON = "deadlypoisondanger"
CLOTHES_GROUND = "groundcowboy"
CLOTHES_ROCK = "temp"
CLOTHES_BUG_1 = "bughakama"
CLOTHES_BUG_2 = "bughakamapants"
CLOTHES_GHOST = "temp"
CLOTHES_STEEL_M = "steelworkerM"
CLOTHES_STEEL_F = "steelworkerF"
CLOTHES_FIRE = "fire"
CLOTHES_WATER = "waterdress"
CLOTHES_GRASS = "temp"
CLOTHES_ELECTRIC = "urbanelectric"
CLOTHES_PSYCHIC = "temp"
CLOTHES_ICE = "iceoutfit"
CLOTHES_DRAGON = "dragonconqueror"
CLOTHES_DARK = "temp"
CLOTHES_FAIRY_M = "mikufairym"
CLOTHES_FAIRY_F = "mikufairyf"
NORMAL_ITEMS = [:NORMALGEM,:MOOMOOMILK,:POTION,:FULLHEAL,:CHILANBERRY,]
FIGHTING_ITEMS = [:FIGHTINGGEM,:PROTEIN,:CHOPLEBERRY,]
FLYING_ITEMS = [:FLYINGGEM,:HEALTHWING,:MUSCLEWING,:RESISTWING,:GENIUSWING,:CLEVERWING,:SWIFTWING,:AIRBALLOON,:PRETTYWING,:COBABERRY, ]
POISON_ITEMS = [:POISONGEM,:ANTIDOTE, :KEBIABERRY, ]
GROUND_ITEMS = [:GROUNDGEM,:SHUCABERRY, ]
ROCK_ITEMS = [:ROCKGEM, :STARDUST,:CHARTIBERRY, ]
BUG_ITEMS = [:BUGGEM,:HONEY,:TANGABERRY, ]
GHOST_ITEMS = [:GHOSTGEM,:KASIBBERRY,]
STEEL_ITEMS = [:STEELGEM,:BABIRIBERRY,:METALPOWDER,]
FIRE_ITEMS = [:FIREGEM,:LAVACOOKIE,:BURNHEAL,:OCCABERRY, ]
WATER_ITEMS = [:WATERGEM,:HEARTSCALE,:PEARL,:PASSHOBERRY ]
GRASS_ITEMS = [:GRASSGEM,:LUMBERRY,:ORANBERRY,:SITRUSBERRY,:GRASSYSEED,:ABSORBBULB,:TINYMUSHROOM, :RINDOBERRY, ]
ELECTRIC_ITEMS = [:ELECTRICGEM,:ELECTRICSEED,:PARLYZHEAL,:CELLBATTERY,:WACANBERRY, ]
PSYCHIC_ITEMS = [:PSYCHICGEM,:PSYCHICSEED, :MENTALHERB, :PAYAPABERRY,]
ICE_ITEMS = [:ICEGEM,:SNOWBALL,:ICEHEAL,:YACHEBERRY, ]
DRAGON_ITEMS = [:DRAGONGEM,:HABANBERRY, ]
DARK_ITEMS = [:DARKGEM,:COLBURBERRY, ]
FAIRY_ITEMS = [:FAIRYGEM,:MISTYSEED, ]
def isWearingElectricOutfit()
return (isWearingClothes(CLOTHES_ELECTRIC))
end
def isWearingNormalOutfit()
return (isWearingClothes(CLOTHES_NORMAL))
end
def isWearingFightingOutfit()
return (isWearingClothes(CLOTHES_FIGHTING))
end
def isWearingFlyingOutfit()
return (isWearingClothes(CLOTHES_FLYING))
end
def isWearingPoisonOutfit()
return (isWearingClothes(CLOTHES_POISON))
end
def isWearingGroundOutfit()
return (isWearingClothes(CLOTHES_GROUND))
end
def isWearingRockOutfit()
return (isWearingClothes(CLOTHES_ROCK))
end
def isWearingBugOutfit()
return ((isWearingClothes(CLOTHES_BUG_1) || isWearingClothes(CLOTHES_BUG_2)))
end
def isWearingGhostOutfit()
return (isWearingClothes(CLOTHES_GHOST))
end
def isWearingSteelOutfit()
return ((isWearingClothes(CLOTHES_STEEL_M) || isWearingClothes(CLOTHES_STEEL_F)))
end
def isWearingFireOutfit()
return (isWearingClothes(CLOTHES_FIRE))
end
def isWearingWaterOutfit()
return (isWearingClothes(CLOTHES_WATER))
end
def isWearingGrassOutfit()
return (isWearingClothes(CLOTHES_GRASS))
end
def isWearingPsychicOutfit()
return (isWearingClothes(CLOTHES_PSYCHIC))
end
def isWearingIceOutfit()
return (isWearingClothes(CLOTHES_ICE))
end
def isWearingDragonOutfit()
return (isWearingClothes(CLOTHES_DRAGON))
end
def isWearingDarkOutfit()
return (isWearingClothes(CLOTHES_DARK))
end
def isWearingFairyOutfit()
return ((isWearingClothes(CLOTHES_FAIRY_M) || isWearingClothes(CLOTHES_FAIRY_F)))
end
def pickUpTypeItemSetBonus()
return if rand(10) != 0
items_list = if isWearingElectricOutfit()
ELECTRIC_ITEMS
elsif isWearingNormalOutfit()
NORMAL_ITEMS
elsif isWearingFightingOutfit()
FIGHTING_ITEMS
elsif isWearingFlyingOutfit()
FLYING_ITEMS
elsif isWearingPoisonOutfit()
POISON_ITEMS
elsif isWearingGroundOutfit()
GROUND_ITEMS
elsif isWearingRockOutfit()
ROCK_ITEMS
elsif isWearingBugOutfit()
BUG_ITEMS
elsif isWearingGhostOutfit()
GHOST_ITEMS
elsif isWearingSteelOutfit()
STEEL_ITEMS
elsif isWearingFireOutfit()
FIRE_ITEMS
elsif isWearingWaterOutfit()
WATER_ITEMS
elsif isWearingGrassOutfit()
GRASS_ITEMS
elsif isWearingPsychicOutfit()
PSYCHIC_ITEMS
elsif isWearingIceOutfit()
ICE_ITEMS
elsif isWearingDragonOutfit()
DRAGON_ITEMS
elsif isWearingDarkOutfit()
DARK_ITEMS
elsif isWearingFairyOutfit()
FAIRY_ITEMS
else
[]
end
if !items_list.empty?
Kernel.pbItemBall(items_list.sample)
end
end

View File

@@ -0,0 +1,148 @@
#Clothes
CLOTHES_TEAM_ROCKET_MALE = "rocketm"
CLOTHES_TEAM_ROCKET_FEMALE = "rocketf"
CLOTHES_OFFICE_WORKER_F = "officeworkerf"
CLOTHES_OFFICE_WORKER_M = "officeworkerm"
CLOTHES_BUSINESS_SUIT = "BusinessSuit"
CLOTHES_ADVENTURER = "fantasyadventurersoutfit"
CLOTHES_EMERALD = "emeraldSPE"
CLOTHES_PIKACHU_ONESIE = "pikaonesie"
CLOTHES_GLITCH = "glitzerset"
CLOTHES_BREEDER="PKMBreeder"
CLOTHES_FOSSIL_M ="sado"
CLOTHES_FOSSIL_F ="sada"
CLOTHES_TREVENANT= "trevenantforestkingcloak"
CLOTHES_WAITRESS = "maid"
CLOTHES_WAITER = "butler"
CLOTHES_LASS_YELLOW ="lass"
CLOTHES_LASS_BLUE ="lass2"
DEFAULT_OUTFIT_MALE = "red"
DEFAULT_OUTFIT_FEMALE = "leaf"
STARTING_OUTFIT = "pikajamas"
#Hats
HAT_TEAM_ROCKET = "rocketcap"
HAT_POSTMAN = "postman"
HAT_PIDGEY_NEST = "pidgey"
HAT_SWABLU_NEST = "swablu"
HAT_PIKACHUM_NEST = "pikhatchum"
HAT_PIKACHUF_NEST = "pikhatchuf"
HAT_PARAS_NEST = "headparas"
HAT_EEVEE_NEST = "eevee"
HAT_PARASHROOM = "parashroom"
HAT_AERODACTYL = "aerodactylSkull"
HAT_DUSKULL_MASK = "duskullmask"
HAT_SLEEPMASK = "sleepmask"
HAT_DITTO_MASK = "creepydittomask"
HAT_EGG = "egg"
HAT_DRIFLOON_CAP = "drifloon"
HAT_EMERALD = "emeraldSPEgem"
HAT_SQUIRTLE_SHADES = "squirtlesquadshades"
HAT_WOOPER = "wooperclips"
HAT_PIKACHU_HOOD = "pikaonesie"
HAT_FEZ = "fez"
HAT_HALO = "halo"
HAT_MAGIKARP = "magicap"
HAT_SLOWKING_SHELL = "slowking"
HAT_ZOROARK = "banefulfoxmask"
HAT_FROG = "froghat"
HAT_SANTA = "santa"
HAT_QMARKS = "glitzerset"
HAT_SUDOWOODO = "sudowoodohorns"
HAT_TREVENANT="trevenantforestkingcrown"
HAT_CLOWN = "clownnose"
HAT_BREEDER_1="breedervisor"
HAT_BREEDER_2="breederbandana"
HAT_BREEDER_2_2="PKMBreeder"
HAT_BREEDER_3="egg"
HAT_BREEDEROUTFIT="PKMBreeder"
HAT_WAITRESS = "maid"
FUSION_HAT = "fusionnerd"
FUSION_OUTFIT = "fusionnerd"
HAT_ASH = "ash"
HAT_BIANCA = "bianca"
HAT_CLEFAIRY = "clefairyearheadband"
HAT_FLOWER = "mikufairy"
HAT_SKITTY_TV = "skittyTV"
HAT_TVHEAD = "tvhead"
HAT_SCRIBBLES1 = "scribbles1"
HAT_SCRIBBLES2 = "scribbles2"
HAT_SCRIBBLES3 = "scribbles3"
HAT_SCRIBBLES4 = "scribbles4"
HAT_CARDBOARD_BOX = "box"
HAT_CAPTAIN = "seacaptain"
HAT_GYM_REWARD_1 = "brockpan"
HAT_GYM_REWARD_2 = "starmieclip"
HAT_GYM_REWARD_3 = "surgeglasses"
HAT_GYM_REWARD_4 = "erikaHeadband"
HAT_GYM_REWARD_5 = "kogascarf"
HAT_GYM_REWARD_6 = "sabrinasballs"
HAT_GYM_REWARD_7 = "blaineGlasses"
HAT_GYM_REWARD_8 = "giovannifedora"
HAT_GYM_REWARD_9 = "luluribbon"
HAT_GYM_REWARD_10 = "kurtsentaihelmet"
HAT_GYM_REWARD_11 = "falknerscage"
HAT_GYM_REWARD_12 = "clairbow"
HAT_GYM_REWARD_13 = "chuckmoustache"
HAT_GYM_REWARD_14 = "prycemask"
HAT_GYM_REWARD_15 = "mortyHeadband"
HAT_GYM_REWARD_16 = "magnemitepin"
#Hairstyles
HAIR_RED = "red"
HAIR_LEAF = "leaf"
HAIR_HEXMANIAC = "HexManiac"
HAIR_LASS = "lass"
HAIR_BALD = "bald"
HAIR_RIVAL = "gary"
HAIR_BROCK = "brock"
HAIR_MISTY1 = "mistyRBY"
HAIR_MISTY2 = "mistyGSC"
HAIR_SURGE = "surge" #does not exist yet
HAIR_ERIKA = "erika"
HAIR_KOGA = "koga" #does not exist yet
HAIR_JANINE = "janine"
HAIR_SABRINA = "sabrinaGSC"
HAIR_BLAINE = "blaine" #does not exist yet
HAIR_GIOVANNI = "giovanni" #does not exist yet
HAIR_WHITNEY = "whitney"
HAIR_KURT = "kurt"
HAIR_FALKNER = "falkner"
HAIR_CLAIR = "clair"
HAIR_CHUCK = "chuck" #does not exist yet
HAIR_PRYCE = "pryce" #does not exist yet
HAIR_MORTY = "morty" #does not exist yet
HAIR_JASMINE = "jasmine" #does not exist yet
HAIR_HOOH = "ho-oh"
HAIR_CRESSELIA = "lunarbob"
HAIR_LYCANROC="lycanrocshorthair"
HAIR_HAPPINY="happinysuit"
HAIR_LATIAS="SpecialLatias"
HAIR_GARDEVOIR="gardevoir"
HAIR_EEVEE="eeveetail"

View File

@@ -0,0 +1,20 @@
# frozen_string_literal: true
class Game_Map
alias pokemonEssentials_GameMap_setup setup
def scroll_direction
return 0 if @scroll_distance_x == 0 && @scroll_distance_y == 0
if @scroll_distance_x < 0
return DIRECTION_LEFT
elsif @scroll_distance_x > 0
return DIRECTION_RIGHT
elsif @scroll_distance_y < 0
return DIRECTION_UP
elsif @scroll_distance_y > 0
return DIRECTION_DOWN
end
return 0
end
end

View File

@@ -0,0 +1,7 @@
# frozen_string_literal: true
class Scene_Map
def reset_player_sprite
@spritesetGlobal.playersprite.updateBitmap
end
end

Some files were not shown because too many files have changed in this diff Show More