mirror of
https://github.com/infinitefusion/infinitefusion-e18.git
synced 2025-12-06 06:01:46 +00:00
Refactoring and tidying
This commit is contained in:
@@ -32,73 +32,6 @@ class Win32API
|
||||
width,height = rect.unpack('l4')[2..3]
|
||||
return width,height
|
||||
end
|
||||
|
||||
=begin
|
||||
# Unused
|
||||
def Win32API.SetWindowText(text)
|
||||
hWnd = pbFindRgssWindow
|
||||
swp = Win32API.new('user32','SetWindowTextA',%(l, p),'i')
|
||||
swp.call(hWnd, text.to_s)
|
||||
end
|
||||
|
||||
# Unused
|
||||
def Win32API.SetWindowPos(w, h)
|
||||
hWnd = pbFindRgssWindow
|
||||
windowrect = Win32API.GetWindowRect
|
||||
clientsize = Win32API.client_size
|
||||
xExtra = windowrect.width-clientsize[0]
|
||||
yExtra = windowrect.height-clientsize[1]
|
||||
swp = Win32API.new('user32','SetWindowPos',%(l,l,i,i,i,i,i),'i')
|
||||
win = swp.call(hWnd,0,windowrect.x,windowrect.y,w+xExtra,h+yExtra,0)
|
||||
return win
|
||||
end
|
||||
|
||||
# Unused
|
||||
def Win32API.GetWindowRect
|
||||
hWnd = pbFindRgssWindow
|
||||
rect = [0,0,0,0].pack('l4')
|
||||
Win32API.new('user32','GetWindowRect',%w(l p),'i').call(hWnd,rect)
|
||||
x,y,width,height = rect.unpack('l4')
|
||||
return Rect.new(x,y,width-x,height-y)
|
||||
end
|
||||
|
||||
# Unused
|
||||
def Win32API.focusWindow
|
||||
window = Win32API.new('user32','ShowWindow','LL','L')
|
||||
hWnd = pbFindRgssWindow
|
||||
window.call(hWnd,9)
|
||||
end
|
||||
|
||||
# Unused
|
||||
def Win32API.fillScreen
|
||||
setWindowLong = Win32API.new('user32','SetWindowLong','LLL','L')
|
||||
setWindowPos = Win32API.new('user32','SetWindowPos','LLIIIII','I')
|
||||
metrics = Win32API.new('user32', 'GetSystemMetrics', 'I', 'I')
|
||||
hWnd = pbFindRgssWindow
|
||||
width = metrics.call(0)
|
||||
height = metrics.call(1)
|
||||
setWindowLong.call(hWnd,-16,0x00000000)
|
||||
setWindowPos.call(hWnd,0,0,0,width,height,0)
|
||||
Win32API.focusWindow
|
||||
return [width,height]
|
||||
end
|
||||
|
||||
# Unused
|
||||
def Win32API.restoreScreen
|
||||
setWindowLong = Win32API.new('user32','SetWindowLong','LLL','L')
|
||||
setWindowPos = Win32API.new('user32','SetWindowPos','LLIIIII','I')
|
||||
metrics = Win32API.new('user32','GetSystemMetrics','I','I')
|
||||
hWnd = pbFindRgssWindow
|
||||
width = SCREEN_WIDTH
|
||||
height = SCREEN_HEIGHT
|
||||
x = [(metrics.call(0)-width)/2,0].max
|
||||
y = [(metrics.call(1)-height)/2,0].max
|
||||
setWindowLong.call(hWnd,-16,0x14CA0000)
|
||||
setWindowPos.call(hWnd,0,x,y,width+6,height+29,0)
|
||||
Win32API.focusWindow
|
||||
return [width,height]
|
||||
end
|
||||
=end
|
||||
end
|
||||
|
||||
|
||||
|
||||
@@ -219,12 +219,6 @@ def pbRepositionMessageWindow(msgwindow, linecount=2)
|
||||
msgwindow.opacity = 0
|
||||
end
|
||||
end
|
||||
if $game_message
|
||||
case $game_message.background
|
||||
when 1 then msgwindow.opacity=0 # dim
|
||||
when 2 then msgwindow.opacity=0 # transparent
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# internal function
|
||||
|
||||
@@ -1,30 +1,11 @@
|
||||
#===============================================================================
|
||||
# Message variables
|
||||
#===============================================================================
|
||||
class Game_Message
|
||||
attr_writer :visible
|
||||
attr_writer :background
|
||||
|
||||
def visible
|
||||
return @visible || false
|
||||
end
|
||||
|
||||
def background
|
||||
return @background || 0
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
#===============================================================================
|
||||
#
|
||||
#===============================================================================
|
||||
class Scene_Map
|
||||
def updatemini
|
||||
oldmws=$game_temp.message_window_showing
|
||||
oldvis=$game_message ? $game_message.visible : false
|
||||
oldvis=false
|
||||
$game_temp.message_window_showing=true
|
||||
$game_message.visible=true if $game_message
|
||||
loop do
|
||||
$game_map.update
|
||||
$game_player.update
|
||||
@@ -39,7 +20,6 @@ class Scene_Map
|
||||
break if $game_temp.transition_processing
|
||||
end
|
||||
$game_temp.message_window_showing=oldmws
|
||||
$game_message.visible=oldvis if $game_message
|
||||
@spriteset.update if @spriteset
|
||||
@message_window.update if @message_window
|
||||
end
|
||||
@@ -52,10 +32,6 @@ class Scene_Battle
|
||||
if self.respond_to?("update_basic")
|
||||
update_basic(true)
|
||||
update_info_viewport # Update information viewport
|
||||
if $game_message && $game_message.visible
|
||||
@info_viewport.visible = false
|
||||
@message_window.visible = true
|
||||
end
|
||||
else
|
||||
oldmws=$game_temp.message_window_showing
|
||||
$game_temp.message_window_showing=true
|
||||
@@ -507,7 +483,6 @@ def pbCreateMessageWindow(viewport=nil,skin=nil)
|
||||
msgwindow.back_opacity=MessageConfig::WindowOpacity
|
||||
pbBottomLeftLines(msgwindow,2)
|
||||
$game_temp.message_window_showing=true if $game_temp
|
||||
$game_message.visible=true if $game_message
|
||||
skin=MessageConfig.pbGetSpeechFrame() if !skin
|
||||
msgwindow.setSkin(skin)
|
||||
return msgwindow
|
||||
@@ -515,7 +490,6 @@ end
|
||||
|
||||
def pbDisposeMessageWindow(msgwindow)
|
||||
$game_temp.message_window_showing=false if $game_temp
|
||||
$game_message.visible=false if $game_message
|
||||
msgwindow.dispose
|
||||
end
|
||||
|
||||
@@ -592,9 +566,8 @@ def pbMessageDisplay(msgwindow,message,letterbyletter=true,commandProc=nil)
|
||||
break if text == last_text
|
||||
end
|
||||
colortag = ""
|
||||
if ($game_message && $game_message.background>0) ||
|
||||
($game_system && $game_system.respond_to?("message_frame") &&
|
||||
$game_system.message_frame != 0)
|
||||
if $game_system && $game_system.respond_to?("message_frame") &&
|
||||
$game_system.message_frame != 0
|
||||
colortag = getSkinColor(msgwindow.windowskin,0,true)
|
||||
else
|
||||
colortag = getSkinColor(msgwindow.windowskin,0,isDarkSkin)
|
||||
@@ -674,11 +647,6 @@ def pbMessageDisplay(msgwindow,message,letterbyletter=true,commandProc=nil)
|
||||
end
|
||||
########## Position message window ##############
|
||||
pbRepositionMessageWindow(msgwindow,linecount)
|
||||
if $game_message && $game_message.background==1
|
||||
msgback = IconSprite.new(0,msgwindow.y,msgwindow.viewport)
|
||||
msgback.z = msgwindow.z-1
|
||||
msgback.setBitmap("Graphics/System/MessageBack")
|
||||
end
|
||||
if facewindow
|
||||
pbPositionNearMsgWindow(facewindow,msgwindow,:left)
|
||||
facewindow.viewport = msgwindow.viewport
|
||||
|
||||
@@ -88,27 +88,27 @@ class PokeBattle_Move
|
||||
baseAcc = pbBaseAccuracy(user,target)
|
||||
return true if baseAcc==0
|
||||
# Calculate all multiplier effects
|
||||
modifiers = []
|
||||
modifiers[BASE_ACC] = baseAcc
|
||||
modifiers[ACC_STAGE] = user.stages[PBStats::ACCURACY]
|
||||
modifiers[EVA_STAGE] = target.stages[PBStats::EVASION]
|
||||
modifiers[ACC_MULT] = 1.0
|
||||
modifiers[EVA_MULT] = 1.0
|
||||
modifiers = {}
|
||||
modifiers[:base_accuracy] = baseAcc
|
||||
modifiers[:accuracy_stage] = user.stages[PBStats::ACCURACY]
|
||||
modifiers[:evasion_stage] = target.stages[PBStats::EVASION]
|
||||
modifiers[:accuracy_multiplier] = 1.0
|
||||
modifiers[:evasion_multiplier] = 1.0
|
||||
pbCalcAccuracyModifiers(user,target,modifiers)
|
||||
# Check if move can't miss
|
||||
return true if modifiers[BASE_ACC]==0
|
||||
return true if modifiers[:base_accuracy] == 0
|
||||
# Calculation
|
||||
accStage = [[modifiers[ACC_STAGE],-6].max,6].min + 6
|
||||
evaStage = [[modifiers[EVA_STAGE],-6].max,6].min + 6
|
||||
accStage = [[modifiers[:accuracy_stage], -6].max, 6].min + 6
|
||||
evaStage = [[modifiers[:evasion_stage], -6].max, 6].min + 6
|
||||
stageMul = [3,3,3,3,3,3, 3, 4,5,6,7,8,9]
|
||||
stageDiv = [9,8,7,6,5,4, 3, 3,3,3,3,3,3]
|
||||
accuracy = 100.0 * stageMul[accStage] / stageDiv[accStage]
|
||||
evasion = 100.0 * stageMul[evaStage] / stageDiv[evaStage]
|
||||
accuracy = (accuracy * modifiers[ACC_MULT]).round
|
||||
evasion = (evasion * modifiers[EVA_MULT]).round
|
||||
accuracy = (accuracy * modifiers[:accuracy_multiplier]).round
|
||||
evasion = (evasion * modifiers[:evasion_multiplier]).round
|
||||
evasion = 1 if evasion < 1
|
||||
# Calculation
|
||||
return @battle.pbRandom(100) < modifiers[BASE_ACC] * accuracy / evasion
|
||||
return @battle.pbRandom(100) < modifiers[:base_accuracy] * accuracy / evasion
|
||||
end
|
||||
|
||||
def pbCalcAccuracyModifiers(user,target,modifiers)
|
||||
@@ -135,16 +135,17 @@ class PokeBattle_Move
|
||||
BattleHandlers.triggerAccuracyCalcTargetItem(target.item,
|
||||
modifiers,user,target,self,@calcType)
|
||||
end
|
||||
# Other effects, inc. ones that set ACC_MULT or EVA_STAGE to specific values
|
||||
# Other effects, inc. ones that set accuracy_multiplier or evasion_stage to
|
||||
# specific values
|
||||
if @battle.field.effects[PBEffects::Gravity] > 0
|
||||
modifiers[ACC_MULT] *= 5/3.0
|
||||
modifiers[:accuracy_multiplier] *= 5 / 3.0
|
||||
end
|
||||
if user.effects[PBEffects::MicleBerry]
|
||||
user.effects[PBEffects::MicleBerry] = false
|
||||
modifiers[ACC_MULT] *= 1.2
|
||||
modifiers[:accuracy_multiplier] *= 1.2
|
||||
end
|
||||
modifiers[EVA_STAGE] = 0 if target.effects[PBEffects::Foresight] && modifiers[EVA_STAGE]>0
|
||||
modifiers[EVA_STAGE] = 0 if target.effects[PBEffects::MiracleEye] && modifiers[EVA_STAGE]>0
|
||||
modifiers[:evasion_stage] = 0 if target.effects[PBEffects::Foresight] && modifiers[:evasion_stage] > 0
|
||||
modifiers[:evasion_stage] = 0 if target.effects[PBEffects::MiracleEye] && modifiers[:evasion_stage] > 0
|
||||
end
|
||||
|
||||
#=============================================================================
|
||||
@@ -241,14 +242,19 @@ class PokeBattle_Move
|
||||
defense = (defense.to_f*stageMul[defStage]/stageDiv[defStage]).floor
|
||||
end
|
||||
# Calculate all multiplier effects
|
||||
multipliers = [1.0, 1.0, 1.0, 1.0]
|
||||
multipliers = {
|
||||
:base_damage_multiplier => 1.0,
|
||||
:attack_multiplier => 1.0,
|
||||
:defense_multiplier => 1.0,
|
||||
:final_damage_multiplier => 1.0
|
||||
}
|
||||
pbCalcDamageMultipliers(user,target,numTargets,type,baseDmg,multipliers)
|
||||
# Main damage calculation
|
||||
baseDmg = [(baseDmg * multipliers[BASE_DMG_MULT]).round, 1].max
|
||||
atk = [(atk * multipliers[ATK_MULT]).round, 1].max
|
||||
defense = [(defense * multipliers[DEF_MULT]).round, 1].max
|
||||
baseDmg = [(baseDmg * multipliers[:base_damage_multiplier]).round, 1].max
|
||||
atk = [(atk * multipliers[:attack_multiplier]).round, 1].max
|
||||
defense = [(defense * multipliers[:defense_multiplier]).round, 1].max
|
||||
damage = (((2.0 * user.level / 5 + 2).floor * baseDmg * atk / defense).floor / 50).floor + 2
|
||||
damage = [(damage * multipliers[FINAL_DMG_MULT]).round, 1].max
|
||||
damage = [(damage * multipliers[:final_damage_multiplier]).round, 1].max
|
||||
target.damageState.calcDamage = damage
|
||||
end
|
||||
|
||||
@@ -257,9 +263,9 @@ class PokeBattle_Move
|
||||
if (@battle.pbCheckGlobalAbility(:DARKAURA) && type == :DARK) ||
|
||||
(@battle.pbCheckGlobalAbility(:FAIRYAURA) && type == :FAIRY)
|
||||
if @battle.pbCheckGlobalAbility(:AURABREAK)
|
||||
multipliers[BASE_DMG_MULT] *= 2/3.0
|
||||
multipliers[:base_damage_multiplier] *= 2 / 3.0
|
||||
else
|
||||
multipliers[BASE_DMG_MULT] *= 4/3.0
|
||||
multipliers[:base_damage_multiplier] *= 4 / 3.0
|
||||
end
|
||||
end
|
||||
# Ability effects that alter damage
|
||||
@@ -299,154 +305,154 @@ class PokeBattle_Move
|
||||
end
|
||||
# Parental Bond's second attack
|
||||
if user.effects[PBEffects::ParentalBond]==1
|
||||
multipliers[BASE_DMG_MULT] /= 4
|
||||
multipliers[:base_damage_multiplier] /= 4
|
||||
end
|
||||
# Other
|
||||
if user.effects[PBEffects::MeFirst]
|
||||
multipliers[BASE_DMG_MULT] *= 1.5
|
||||
multipliers[:base_damage_multiplier] *= 1.5
|
||||
end
|
||||
if user.effects[PBEffects::HelpingHand] && !self.is_a?(PokeBattle_Confusion)
|
||||
multipliers[BASE_DMG_MULT] *= 1.5
|
||||
multipliers[:base_damage_multiplier] *= 1.5
|
||||
end
|
||||
if user.effects[PBEffects::Charge]>0 && type == :ELECTRIC
|
||||
multipliers[BASE_DMG_MULT] *= 2
|
||||
multipliers[:base_damage_multiplier] *= 2
|
||||
end
|
||||
# Mud Sport
|
||||
if type == :ELECTRIC
|
||||
@battle.eachBattler do |b|
|
||||
next if !b.effects[PBEffects::MudSport]
|
||||
multipliers[BASE_DMG_MULT] /= 3
|
||||
multipliers[:base_damage_multiplier] /= 3
|
||||
break
|
||||
end
|
||||
if @battle.field.effects[PBEffects::MudSportField]>0
|
||||
multipliers[BASE_DMG_MULT] /= 3
|
||||
multipliers[:base_damage_multiplier] /= 3
|
||||
end
|
||||
end
|
||||
# Water Sport
|
||||
if type == :FIRE
|
||||
@battle.eachBattler do |b|
|
||||
next if !b.effects[PBEffects::WaterSport]
|
||||
multipliers[BASE_DMG_MULT] /= 3
|
||||
multipliers[:base_damage_multiplier] /= 3
|
||||
break
|
||||
end
|
||||
if @battle.field.effects[PBEffects::WaterSportField]>0
|
||||
multipliers[BASE_DMG_MULT] /= 3
|
||||
multipliers[:base_damage_multiplier] /= 3
|
||||
end
|
||||
end
|
||||
# Terrain moves
|
||||
if user.affectedByTerrain?
|
||||
case @battle.field.terrain
|
||||
when PBBattleTerrains::Electric
|
||||
multipliers[BASE_DMG_MULT] *= 1.5 if type == :ELECTRIC
|
||||
multipliers[:base_damage_multiplier] *= 1.5 if type == :ELECTRIC
|
||||
when PBBattleTerrains::Grassy
|
||||
multipliers[BASE_DMG_MULT] *= 1.5 if type == :GRASS
|
||||
multipliers[:base_damage_multiplier] *= 1.5 if type == :GRASS
|
||||
when PBBattleTerrains::Psychic
|
||||
multipliers[BASE_DMG_MULT] *= 1.5 if type == :PSYCHIC
|
||||
multipliers[:base_damage_multiplier] *= 1.5 if type == :PSYCHIC
|
||||
end
|
||||
end
|
||||
if @battle.field.terrain==PBBattleTerrains::Misty && target.affectedByTerrain? &&
|
||||
type == :DRAGON
|
||||
multipliers[BASE_DMG_MULT] /= 2
|
||||
multipliers[:base_damage_multiplier] /= 2
|
||||
end
|
||||
# Badge multipliers
|
||||
if @battle.internalBattle
|
||||
if user.pbOwnedByPlayer?
|
||||
if physicalMove? && @battle.pbPlayer.numbadges >= NUM_BADGES_BOOST_ATTACK
|
||||
multipliers[ATK_MULT] *= 1.1
|
||||
multipliers[:attack_multiplier] *= 1.1
|
||||
elsif specialMove? && @battle.pbPlayer.numbadges >= NUM_BADGES_BOOST_SPATK
|
||||
multipliers[ATK_MULT] *= 1.1
|
||||
multipliers[:attack_multiplier] *= 1.1
|
||||
end
|
||||
end
|
||||
if target.pbOwnedByPlayer?
|
||||
if physicalMove? && @battle.pbPlayer.numbadges >= NUM_BADGES_BOOST_DEFENSE
|
||||
multipliers[DEF_MULT] *= 1.1
|
||||
multipliers[:defense_multiplier] *= 1.1
|
||||
elsif specialMove? && @battle.pbPlayer.numbadges >= NUM_BADGES_BOOST_SPDEF
|
||||
multipliers[DEF_MULT] *= 1.1
|
||||
multipliers[:defense_multiplier] *= 1.1
|
||||
end
|
||||
end
|
||||
end
|
||||
# Multi-targeting attacks
|
||||
if numTargets>1
|
||||
multipliers[FINAL_DMG_MULT] *= 0.75
|
||||
multipliers[:final_damage_multiplier] *= 0.75
|
||||
end
|
||||
# Weather
|
||||
case @battle.pbWeather
|
||||
when PBWeather::Sun, PBWeather::HarshSun
|
||||
if type == :FIRE
|
||||
multipliers[FINAL_DMG_MULT] *= 1.5
|
||||
multipliers[:final_damage_multiplier] *= 1.5
|
||||
elsif type == :WATER
|
||||
multipliers[FINAL_DMG_MULT] /= 2
|
||||
multipliers[:final_damage_multiplier] /= 2
|
||||
end
|
||||
when PBWeather::Rain, PBWeather::HeavyRain
|
||||
if type == :FIRE
|
||||
multipliers[FINAL_DMG_MULT] /= 2
|
||||
multipliers[:final_damage_multiplier] /= 2
|
||||
elsif type == :WATER
|
||||
multipliers[FINAL_DMG_MULT] *= 1.5
|
||||
multipliers[:final_damage_multiplier] *= 1.5
|
||||
end
|
||||
when PBWeather::Sandstorm
|
||||
if target.pbHasType?(:ROCK) && specialMove? && @function != "122" # Psyshock
|
||||
multipliers[DEF_MULT] *= 1.5
|
||||
multipliers[:defense_multiplier] *= 1.5
|
||||
end
|
||||
end
|
||||
# Critical hits
|
||||
if target.damageState.critical
|
||||
if NEW_CRITICAL_HIT_RATE_MECHANICS
|
||||
multipliers[FINAL_DMG_MULT] *= 1.5
|
||||
multipliers[:final_damage_multiplier] *= 1.5
|
||||
else
|
||||
multipliers[FINAL_DMG_MULT] *= 2
|
||||
multipliers[:final_damage_multiplier] *= 2
|
||||
end
|
||||
end
|
||||
# Random variance
|
||||
if !self.is_a?(PokeBattle_Confusion)
|
||||
random = 85+@battle.pbRandom(16)
|
||||
multipliers[FINAL_DMG_MULT] *= random/100.0
|
||||
multipliers[:final_damage_multiplier] *= random / 100.0
|
||||
end
|
||||
# STAB
|
||||
if type && user.pbHasType?(type)
|
||||
if user.hasActiveAbility?(:ADAPTABILITY)
|
||||
multipliers[FINAL_DMG_MULT] *= 2
|
||||
multipliers[:final_damage_multiplier] *= 2
|
||||
else
|
||||
multipliers[FINAL_DMG_MULT] *= 1.5
|
||||
multipliers[:final_damage_multiplier] *= 1.5
|
||||
end
|
||||
end
|
||||
# Type effectiveness
|
||||
multipliers[FINAL_DMG_MULT] *= target.damageState.typeMod.to_f/PBTypeEffectiveness::NORMAL_EFFECTIVE
|
||||
multipliers[:final_damage_multiplier] *= target.damageState.typeMod.to_f / PBTypeEffectiveness::NORMAL_EFFECTIVE
|
||||
# Burn
|
||||
if user.status==PBStatuses::BURN && physicalMove? && damageReducedByBurn? &&
|
||||
!user.hasActiveAbility?(:GUTS)
|
||||
multipliers[FINAL_DMG_MULT] /= 2
|
||||
multipliers[:final_damage_multiplier] /= 2
|
||||
end
|
||||
# Aurora Veil, Reflect, Light Screen
|
||||
if !ignoresReflect? && !target.damageState.critical &&
|
||||
!user.hasActiveAbility?(:INFILTRATOR)
|
||||
if target.pbOwnSide.effects[PBEffects::AuroraVeil] > 0
|
||||
if @battle.pbSideBattlerCount(target)>1
|
||||
multipliers[FINAL_DMG_MULT] *= 2/3.0
|
||||
multipliers[:final_damage_multiplier] *= 2 / 3.0
|
||||
else
|
||||
multipliers[FINAL_DMG_MULT] /= 2
|
||||
multipliers[:final_damage_multiplier] /= 2
|
||||
end
|
||||
elsif target.pbOwnSide.effects[PBEffects::Reflect] > 0 && physicalMove?
|
||||
if @battle.pbSideBattlerCount(target)>1
|
||||
multipliers[FINAL_DMG_MULT] *= 2/3.0
|
||||
multipliers[:final_damage_multiplier] *= 2 / 3.0
|
||||
else
|
||||
multipliers[FINAL_DMG_MULT] /= 2
|
||||
multipliers[:final_damage_multiplier] /= 2
|
||||
end
|
||||
elsif target.pbOwnSide.effects[PBEffects::LightScreen] > 0 && specialMove?
|
||||
if @battle.pbSideBattlerCount(target) > 1
|
||||
multipliers[FINAL_DMG_MULT] *= 2/3.0
|
||||
multipliers[:final_damage_multiplier] *= 2 / 3.0
|
||||
else
|
||||
multipliers[FINAL_DMG_MULT] /= 2
|
||||
multipliers[:final_damage_multiplier] /= 2
|
||||
end
|
||||
end
|
||||
end
|
||||
# Minimize
|
||||
if target.effects[PBEffects::Minimize] && tramplesMinimize?(2)
|
||||
multipliers[FINAL_DMG_MULT] *= 2
|
||||
multipliers[:final_damage_multiplier] *= 2
|
||||
end
|
||||
# Move-specific base damage modifiers
|
||||
multipliers[BASE_DMG_MULT] = pbBaseDamageMultiplier(multipliers[BASE_DMG_MULT],user,target)
|
||||
multipliers[:base_damage_multiplier] = pbBaseDamageMultiplier(multipliers[:base_damage_multiplier], user, target)
|
||||
# Move-specific final damage modifiers
|
||||
multipliers[FINAL_DMG_MULT] = pbModifyDamage(multipliers[FINAL_DMG_MULT],user,target)
|
||||
multipliers[:final_damage_multiplier] = pbModifyDamage(multipliers[:final_damage_multiplier], user, target)
|
||||
end
|
||||
|
||||
#=============================================================================
|
||||
|
||||
@@ -1035,7 +1035,7 @@ end
|
||||
class PokeBattle_Move_0A9 < PokeBattle_Move
|
||||
def pbCalcAccuracyMultipliers(user,target,multipliers)
|
||||
super
|
||||
modifiers[EVA_STAGE] = 0 # Accuracy stat stage
|
||||
modifiers[:evasion_stage] = 0
|
||||
end
|
||||
|
||||
def pbGetDefenseStats(user,target)
|
||||
|
||||
@@ -274,7 +274,12 @@ class PokeBattle_AI
|
||||
defense = pbRoughStat(target,PBStats::SPDEF,skill)
|
||||
end
|
||||
##### Calculate all multiplier effects #####
|
||||
multipliers = [1.0, 1.0, 1.0, 1.0]
|
||||
multipliers = {
|
||||
:base_damage_multiplier => 1.0,
|
||||
:attack_multiplier => 1.0,
|
||||
:defense_multiplier => 1.0,
|
||||
:final_damage_multiplier => 1.0
|
||||
}
|
||||
# Ability effects that alter damage
|
||||
moldBreaker = false
|
||||
if skill>=PBTrainerAI.highSkill && target.hasMoldBreaker?
|
||||
@@ -349,15 +354,15 @@ class PokeBattle_AI
|
||||
if (@battle.pbCheckGlobalAbility(:DARKAURA) && type == :DARK) ||
|
||||
(@battle.pbCheckGlobalAbility(:FAIRYAURA) && type == :FAIRY)
|
||||
if @battle.pbCheckGlobalAbility(:AURABREAK)
|
||||
multipliers[BASE_DMG_MULT] *= 2/3
|
||||
multipliers[:base_damage_multiplier] *= 2 / 3.0
|
||||
else
|
||||
multipliers[BASE_DMG_MULT] *= 4/3
|
||||
multipliers[:base_damage_multiplier] *= 4 / 3.0
|
||||
end
|
||||
end
|
||||
end
|
||||
# Parental Bond
|
||||
if skill>=PBTrainerAI.mediumSkill && user.hasActiveAbility?(:PARENTALBOND)
|
||||
multipliers[BASE_DMG_MULT] *= 1.25
|
||||
multipliers[:base_damage_multiplier] *= 1.25
|
||||
end
|
||||
# Me First
|
||||
# TODO
|
||||
@@ -365,7 +370,7 @@ class PokeBattle_AI
|
||||
# Charge
|
||||
if skill>=PBTrainerAI.mediumSkill
|
||||
if user.effects[PBEffects::Charge]>0 && type == :ELECTRIC
|
||||
multipliers[BASE_DMG_MULT] *= 2
|
||||
multipliers[:base_damage_multiplier] *= 2
|
||||
end
|
||||
end
|
||||
# Mud Sport and Water Sport
|
||||
@@ -373,21 +378,21 @@ class PokeBattle_AI
|
||||
if type == :ELECTRIC
|
||||
@battle.eachBattler do |b|
|
||||
next if !b.effects[PBEffects::MudSport]
|
||||
multipliers[BASE_DMG_MULT] /= 3
|
||||
multipliers[:base_damage_multiplier] /= 3
|
||||
break
|
||||
end
|
||||
if @battle.field.effects[PBEffects::MudSportField]>0
|
||||
multipliers[BASE_DMG_MULT] /= 3
|
||||
multipliers[:base_damage_multiplier] /= 3
|
||||
end
|
||||
end
|
||||
if type == :FIRE
|
||||
@battle.eachBattler do |b|
|
||||
next if !b.effects[PBEffects::WaterSport]
|
||||
multipliers[BASE_DMG_MULT] /= 3
|
||||
multipliers[:base_damage_multiplier] /= 3
|
||||
break
|
||||
end
|
||||
if @battle.field.effects[PBEffects::WaterSportField]>0
|
||||
multipliers[BASE_DMG_MULT] /= 3
|
||||
multipliers[:base_damage_multiplier] /= 3
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -395,16 +400,16 @@ class PokeBattle_AI
|
||||
if user.affectedByTerrain? && skill>=PBTrainerAI.mediumSkill
|
||||
case @battle.field.terrain
|
||||
when PBBattleTerrains::Electric
|
||||
multipliers[BASE_DMG_MULT] *= 1.5 if type == :ELECTRIC
|
||||
multipliers[:base_damage_multiplier] *= 1.5 if type == :ELECTRIC
|
||||
when PBBattleTerrains::Grassy
|
||||
multipliers[BASE_DMG_MULT] *= 1.5 if type == :GRASS
|
||||
multipliers[:base_damage_multiplier] *= 1.5 if type == :GRASS
|
||||
when PBBattleTerrains::Psychic
|
||||
multipliers[BASE_DMG_MULT] *= 1.5 if type == :PSYCHIC
|
||||
multipliers[:base_damage_multiplier] *= 1.5 if type == :PSYCHIC
|
||||
end
|
||||
end
|
||||
if target.affectedByTerrain? && skill>=PBTrainerAI.mediumSkill
|
||||
if @battle.field.terrain==PBBattleTerrains::Misty && type == :DRAGON
|
||||
multipliers[BASE_DMG_MULT] /= 2
|
||||
multipliers[:base_damage_multiplier] /= 2
|
||||
end
|
||||
end
|
||||
# Badge multipliers
|
||||
@@ -414,9 +419,9 @@ class PokeBattle_AI
|
||||
# won't control the player's Pokémon.
|
||||
if target.pbOwnedByPlayer?
|
||||
if move.physicalMove?(type) && @battle.pbPlayer.numbadges >= NUM_BADGES_BOOST_DEFENSE
|
||||
multipliers[DEF_MULT] *= 1.1
|
||||
multipliers[:defense_multiplier] *= 1.1
|
||||
elsif move.specialMove?(type) && @battle.pbPlayer.numbadges >= NUM_BADGES_BOOST_SPDEF
|
||||
multipliers[DEF_MULT] *= 1.1
|
||||
multipliers[:defense_multiplier] *= 1.1
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -424,7 +429,7 @@ class PokeBattle_AI
|
||||
# Multi-targeting attacks
|
||||
if skill>=PBTrainerAI.highSkill
|
||||
if pbTargetsMultiple?(move,user)
|
||||
multipliers[FINAL_DMG_MULT] *= 0.75
|
||||
multipliers[:final_damage_multiplier] *= 0.75
|
||||
end
|
||||
end
|
||||
# Weather
|
||||
@@ -432,19 +437,19 @@ class PokeBattle_AI
|
||||
case @battle.pbWeather
|
||||
when PBWeather::Sun, PBWeather::HarshSun
|
||||
if type == :FIRE
|
||||
multipliers[FINAL_DMG_MULT] *= 1.5
|
||||
multipliers[:final_damage_multiplier] *= 1.5
|
||||
elsif type == :WATER
|
||||
multipliers[FINAL_DMG_MULT] /= 2
|
||||
multipliers[:final_damage_multiplier] /= 2
|
||||
end
|
||||
when PBWeather::Rain, PBWeather::HeavyRain
|
||||
if type == :FIRE
|
||||
multipliers[FINAL_DMG_MULT] /= 2
|
||||
multipliers[:final_damage_multiplier] /= 2
|
||||
elsif type == :WATER
|
||||
multipliers[FINAL_DMG_MULT] *= 1.5
|
||||
multipliers[:final_damage_multiplier] *= 1.5
|
||||
end
|
||||
when PBWeather::Sandstorm
|
||||
if target.pbHasType?(:ROCK) && move.specialMove?(type) && move.function != "122" # Psyshock
|
||||
multipliers[DEF_MULT] *= 1.5
|
||||
multipliers[:defense_multiplier] *= 1.5
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -454,23 +459,23 @@ class PokeBattle_AI
|
||||
if skill>=PBTrainerAI.mediumSkill
|
||||
if type && user.pbHasType?(type)
|
||||
if user.hasActiveAbility?(:ADAPTABILITY)
|
||||
multipliers[FINAL_DMG_MULT] *= 2
|
||||
multipliers[:final_damage_multiplier] *= 2
|
||||
else
|
||||
multipliers[FINAL_DMG_MULT] *= 1.5
|
||||
multipliers[:final_damage_multiplier] *= 1.5
|
||||
end
|
||||
end
|
||||
end
|
||||
# Type effectiveness
|
||||
if skill>=PBTrainerAI.mediumSkill
|
||||
typemod = pbCalcTypeMod(type,user,target)
|
||||
multipliers[FINAL_DMG_MULT] *= typemod.to_f/PBTypeEffectiveness::NORMAL_EFFECTIVE
|
||||
multipliers[:final_damage_multiplier] *= typemod.to_f / PBTypeEffectiveness::NORMAL_EFFECTIVE
|
||||
end
|
||||
# Burn
|
||||
if skill>=PBTrainerAI.highSkill
|
||||
if user.status==PBStatuses::BURN && move.physicalMove?(type) &&
|
||||
!user.hasActiveAbility?(:GUTS) &&
|
||||
!(MECHANICS_GENERATION >= 6 && move.function == "07E") # Facade
|
||||
multipliers[FINAL_DMG_MULT] /= 2
|
||||
multipliers[:final_damage_multiplier] /= 2
|
||||
end
|
||||
end
|
||||
# Aurora Veil, Reflect, Light Screen
|
||||
@@ -478,21 +483,21 @@ class PokeBattle_AI
|
||||
if !move.ignoresReflect? && !user.hasActiveAbility?(:INFILTRATOR)
|
||||
if target.pbOwnSide.effects[PBEffects::AuroraVeil] > 0
|
||||
if @battle.pbSideBattlerCount(target) > 1
|
||||
multipliers[FINAL_DMG_MULT] *= 2/3.0
|
||||
multipliers[:final_damage_multiplier] *= 2 / 3.0
|
||||
else
|
||||
multipliers[FINAL_DMG_MULT] /= 2
|
||||
multipliers[:final_damage_multiplier] /= 2
|
||||
end
|
||||
elsif target.pbOwnSide.effects[PBEffects::Reflect] > 0 && move.physicalMove?(type)
|
||||
if @battle.pbSideBattlerCount(target) > 1
|
||||
multipliers[FINAL_DMG_MULT] *= 2/3.0
|
||||
multipliers[:final_damage_multiplier] *= 2 / 3.0
|
||||
else
|
||||
multipliers[FINAL_DMG_MULT] /= 2
|
||||
multipliers[:final_damage_multiplier] /= 2
|
||||
end
|
||||
elsif target.pbOwnSide.effects[PBEffects::LightScreen] > 0 && move.specialMove?(type)
|
||||
if @battle.pbSideBattlerCount(target) > 1
|
||||
multipliers[FINAL_DMG_MULT] *= 2/3.0
|
||||
multipliers[:final_damage_multiplier] *= 2 / 3.0
|
||||
else
|
||||
multipliers[FINAL_DMG_MULT] /= 2
|
||||
multipliers[:final_damage_multiplier] /= 2
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -500,7 +505,7 @@ class PokeBattle_AI
|
||||
# Minimize
|
||||
if skill>=PBTrainerAI.highSkill
|
||||
if target.effects[PBEffects::Minimize] && move.tramplesMinimize?(2)
|
||||
multipliers[FINAL_DMG_MULT] *= 2
|
||||
multipliers[:final_damage_multiplier] *= 2
|
||||
end
|
||||
end
|
||||
# Move-specific base damage modifiers
|
||||
@@ -508,11 +513,11 @@ class PokeBattle_AI
|
||||
# Move-specific final damage modifiers
|
||||
# TODO
|
||||
##### Main damage calculation #####
|
||||
baseDmg = [(baseDmg * multipliers[BASE_DMG_MULT]).round, 1].max
|
||||
atk = [(atk * multipliers[ATK_MULT]).round, 1].max
|
||||
defense = [(defense * multipliers[DEF_MULT]).round, 1].max
|
||||
baseDmg = [(baseDmg * multipliers[:base_damage_multiplier]).round, 1].max
|
||||
atk = [(atk * multipliers[:attack_multiplier]).round, 1].max
|
||||
defense = [(defense * multipliers[:defense_multiplier]).round, 1].max
|
||||
damage = (((2.0 * user.level / 5 + 2).floor * baseDmg * atk / defense).floor / 50).floor + 2
|
||||
damage = [(damage * multipliers[FINAL_DMG_MULT]).round, 1].max
|
||||
damage = [(damage * multipliers[:final_damage_multiplier]).round, 1].max
|
||||
# "AI-specific calculations below"
|
||||
# Increased critical hit rates
|
||||
if skill>=PBTrainerAI.mediumSkill
|
||||
@@ -567,26 +572,26 @@ class PokeBattle_AI
|
||||
# Get the move's type
|
||||
type = pbRoughType(move,user,skill)
|
||||
# Calculate all modifier effects
|
||||
modifiers = []
|
||||
modifiers[BASE_ACC] = baseAcc
|
||||
modifiers[ACC_STAGE] = user.stages[PBStats::ACCURACY]
|
||||
modifiers[EVA_STAGE] = target.stages[PBStats::EVASION]
|
||||
modifiers[ACC_MULT] = 1.0
|
||||
modifiers[EVA_MULT] = 1.0
|
||||
modifiers = {}
|
||||
modifiers[:base_accuracy] = baseAcc
|
||||
modifiers[:accuracy_stage] = user.stages[PBStats::ACCURACY]
|
||||
modifiers[:evasion_stage] = target.stages[PBStats::EVASION]
|
||||
modifiers[:accuracy_multiplier] = 1.0
|
||||
modifiers[:evasion_multiplier] = 1.0
|
||||
pbCalcAccuracyModifiers(user,target,modifiers,move,type,skill)
|
||||
# Check if move can't miss
|
||||
return 125 if modifiers[BASE_ACC]==0
|
||||
return 125 if modifiers[:base_accuracy]==0
|
||||
# Calculation
|
||||
accStage = [[modifiers[ACC_STAGE],-6].max,6].min + 6
|
||||
evaStage = [[modifiers[EVA_STAGE],-6].max,6].min + 6
|
||||
accStage = [[modifiers[:accuracy_stage], -6].max, 6].min + 6
|
||||
evaStage = [[modifiers[:evasion_stage], -6].max, 6].min + 6
|
||||
stageMul = [3,3,3,3,3,3, 3, 4,5,6,7,8,9]
|
||||
stageDiv = [9,8,7,6,5,4, 3, 3,3,3,3,3,3]
|
||||
accuracy = 100.0 * stageMul[accStage] / stageDiv[accStage]
|
||||
evasion = 100.0 * stageMul[evaStage] / stageDiv[evaStage]
|
||||
accuracy = (accuracy * modifiers[ACC_MULT]).round
|
||||
evasion = (evasion * modifiers[EVA_MULT]).round
|
||||
accuracy = (accuracy * modifiers[:accuracy_multiplier]).round
|
||||
evasion = (evasion * modifiers[:evasion_multiplier]).round
|
||||
evasion = 1 if evasion<1
|
||||
return modifiers[BASE_ACC] * accuracy / evasion
|
||||
return modifiers[:base_accuracy] * accuracy / evasion
|
||||
end
|
||||
|
||||
def pbCalcAccuracyModifiers(user,target,modifiers,move,type,skill)
|
||||
@@ -625,35 +630,35 @@ class PokeBattle_AI
|
||||
modifiers,user,target,move,type)
|
||||
end
|
||||
end
|
||||
# Other effects, inc. ones that set ACC_MULT or EVA_STAGE to specific values
|
||||
# Other effects, inc. ones that set accuracy_multiplier or evasion_stage to specific values
|
||||
if skill>=PBTrainerAI.mediumSkill
|
||||
if @battle.field.effects[PBEffects::Gravity] > 0
|
||||
modifiers[ACC_MULT] *= 5/3.0
|
||||
modifiers[:accuracy_multiplier] *= 5/3.0
|
||||
end
|
||||
if user.effects[PBEffects::MicleBerry]
|
||||
modifiers[ACC_MULT] *= 1.2
|
||||
modifiers[:accuracy_multiplier] *= 1.2
|
||||
end
|
||||
modifiers[EVA_STAGE] = 0 if target.effects[PBEffects::Foresight] && modifiers[EVA_STAGE]>0
|
||||
modifiers[EVA_STAGE] = 0 if target.effects[PBEffects::MiracleEye] && modifiers[EVA_STAGE]>0
|
||||
modifiers[:evasion_stage] = 0 if target.effects[PBEffects::Foresight] && modifiers[:evasion_stage] > 0
|
||||
modifiers[:evasion_stage] = 0 if target.effects[PBEffects::MiracleEye] && modifiers[:evasion_stage] > 0
|
||||
end
|
||||
# "AI-specific calculations below"
|
||||
if skill>=PBTrainerAI.mediumSkill
|
||||
modifiers[EVA_STAGE] = 0 if move.function=="0A9" # Chip Away
|
||||
modifiers[BASE_ACC] = 0 if ["0A5","139","13A","13B","13C", # "Always hit"
|
||||
modifiers[:evasion_stage] = 0 if move.function == "0A9" # Chip Away
|
||||
modifiers[:base_accuracy] = 0 if ["0A5", "139", "13A", "13B", "13C", # "Always hit"
|
||||
"147"].include?(move.function)
|
||||
modifiers[BASE_ACC] = 0 if user.effects[PBEffects::LockOn]>0 &&
|
||||
modifiers[:base_accuracy] = 0 if user.effects[PBEffects::LockOn]>0 &&
|
||||
user.effects[PBEffects::LockOnPos]==target.index
|
||||
end
|
||||
if skill>=PBTrainerAI.highSkill
|
||||
if move.function=="006" # Toxic
|
||||
modifiers[BASE_ACC] = 0 if MORE_TYPE_EFFECTS && move.statusMove? &&
|
||||
modifiers[:base_accuracy] = 0 if MORE_TYPE_EFFECTS && move.statusMove? &&
|
||||
user.pbHasType?(:POISON)
|
||||
end
|
||||
if move.function=="070" # OHKO moves
|
||||
modifiers[BASE_ACC] = move.accuracy+user.level-target.level
|
||||
modifiers[ACC_MULT] = 0 if target.level>user.level
|
||||
modifiers[:base_accuracy] = move.accuracy + user.level - target.level
|
||||
modifiers[:accuracy_multiplier] = 0 if target.level > user.level
|
||||
if skill>=PBTrainerAI.bestSkill
|
||||
modifiers[ACC_MULT] = 0 if target.hasActiveAbility?(:STURDY)
|
||||
modifiers[:accuracy_multiplier] = 0 if target.hasActiveAbility?(:STURDY)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -478,17 +478,6 @@ end
|
||||
|
||||
|
||||
|
||||
BASE_ACC = 0
|
||||
ACC_STAGE = 1
|
||||
EVA_STAGE = 2
|
||||
ACC_MULT = 3
|
||||
EVA_MULT = 4
|
||||
|
||||
BASE_DMG_MULT = 0
|
||||
ATK_MULT = 1
|
||||
DEF_MULT = 2
|
||||
FINAL_DMG_MULT = 3
|
||||
|
||||
def pbBattleConfusionBerry(battler,battle,item,forced,flavor,confuseMsg)
|
||||
return false if !forced && !battler.canHeal?
|
||||
return false if !forced && !battler.canConsumePinchBerry?(MECHANICS_GENERATION >= 7)
|
||||
@@ -582,16 +571,16 @@ def pbBattleGem(user,type,move,mults,moveType)
|
||||
return if moveType != type
|
||||
user.effects[PBEffects::GemConsumed] = user.item_id
|
||||
if MECHANICS_GENERATION >= 6
|
||||
mults[BASE_DMG_MULT] *= 1.3
|
||||
mults[:base_damage_multiplier] *= 1.3
|
||||
else
|
||||
mults[BASE_DMG_MULT] *= 1.5
|
||||
mults[:base_damage_multiplier] *= 1.5
|
||||
end
|
||||
end
|
||||
|
||||
def pbBattleTypeWeakingBerry(type,moveType,target,mults)
|
||||
return if moveType != type
|
||||
return if PBTypeEffectiveness.resistant?(target.damageState.typeMod) && moveType != :NORMAL
|
||||
mults[FINAL_DMG_MULT] /= 2
|
||||
mults[:final_damage_multiplier] /= 2
|
||||
target.damageState.berryWeakened = true
|
||||
target.battle.pbCommonAnimation("EatBerry",target)
|
||||
end
|
||||
|
||||
@@ -768,37 +768,37 @@ BattleHandlers::MoveBaseTypeModifierAbility.add(:REFRIGERATE,
|
||||
|
||||
BattleHandlers::AccuracyCalcUserAbility.add(:COMPOUNDEYES,
|
||||
proc { |ability,mods,user,target,move,type|
|
||||
mods[ACC_MULT] *= 1.3
|
||||
mods[:accuracy_multiplier] *= 1.3
|
||||
}
|
||||
)
|
||||
|
||||
BattleHandlers::AccuracyCalcUserAbility.add(:HUSTLE,
|
||||
proc { |ability,mods,user,target,move,type|
|
||||
mods[ACC_MULT] *= 0.8 if move.physicalMove?
|
||||
mods[:accuracy_multiplier] *= 0.8 if move.physicalMove?
|
||||
}
|
||||
)
|
||||
|
||||
BattleHandlers::AccuracyCalcUserAbility.add(:KEENEYE,
|
||||
proc { |ability,mods,user,target,move,type|
|
||||
mods[EVA_STAGE] = 0 if mods[EVA_STAGE]>0 && MECHANICS_GENERATION >= 6
|
||||
mods[:evasion_stage] = 0 if mods[:evasion_stage] > 0 && MECHANICS_GENERATION >= 6
|
||||
}
|
||||
)
|
||||
|
||||
BattleHandlers::AccuracyCalcUserAbility.add(:NOGUARD,
|
||||
proc { |ability,mods,user,target,move,type|
|
||||
mods[BASE_ACC] = 0
|
||||
mods[:base_accuracy] = 0
|
||||
}
|
||||
)
|
||||
|
||||
BattleHandlers::AccuracyCalcUserAbility.add(:UNAWARE,
|
||||
proc { |ability,mods,user,target,move,type|
|
||||
mods[EVA_STAGE] = 0 if move.damagingMove?
|
||||
mods[:evasion_stage] = 0 if move.damagingMove?
|
||||
}
|
||||
)
|
||||
|
||||
BattleHandlers::AccuracyCalcUserAbility.add(:VICTORYSTAR,
|
||||
proc { |ability,mods,user,target,move,type|
|
||||
mods[ACC_MULT] *= 1.1
|
||||
mods[:accuracy_multiplier] *= 1.1
|
||||
}
|
||||
)
|
||||
|
||||
@@ -808,7 +808,7 @@ BattleHandlers::AccuracyCalcUserAbility.add(:VICTORYSTAR,
|
||||
|
||||
BattleHandlers::AccuracyCalcUserAllyAbility.add(:VICTORYSTAR,
|
||||
proc { |ability,mods,user,target,move,type|
|
||||
mods[ACC_MULT] *= 1.1
|
||||
mods[:accuracy_multiplier] *= 1.1
|
||||
}
|
||||
)
|
||||
|
||||
@@ -818,20 +818,20 @@ BattleHandlers::AccuracyCalcUserAllyAbility.add(:VICTORYSTAR,
|
||||
|
||||
BattleHandlers::AccuracyCalcTargetAbility.add(:LIGHTNINGROD,
|
||||
proc { |ability,mods,user,target,move,type|
|
||||
mods[BASE_ACC] = 0 if type == :ELECTRIC
|
||||
mods[:base_accuracy] = 0 if type == :ELECTRIC
|
||||
}
|
||||
)
|
||||
|
||||
BattleHandlers::AccuracyCalcTargetAbility.add(:NOGUARD,
|
||||
proc { |ability,mods,user,target,move,type|
|
||||
mods[BASE_ACC] = 0
|
||||
mods[:base_accuracy] = 0
|
||||
}
|
||||
)
|
||||
|
||||
BattleHandlers::AccuracyCalcTargetAbility.add(:SANDVEIL,
|
||||
proc { |ability,mods,user,target,move,type|
|
||||
if target.battle.pbWeather==PBWeather::Sandstorm
|
||||
mods[EVA_MULT] *= 1.25
|
||||
mods[:evasion_multiplier] *= 1.25
|
||||
end
|
||||
}
|
||||
)
|
||||
@@ -839,33 +839,33 @@ BattleHandlers::AccuracyCalcTargetAbility.add(:SANDVEIL,
|
||||
BattleHandlers::AccuracyCalcTargetAbility.add(:SNOWCLOAK,
|
||||
proc { |ability,mods,user,target,move,type|
|
||||
if target.battle.pbWeather==PBWeather::Hail
|
||||
mods[EVA_MULT] *= 1.25
|
||||
mods[:evasion_multiplier] *= 1.25
|
||||
end
|
||||
}
|
||||
)
|
||||
|
||||
BattleHandlers::AccuracyCalcTargetAbility.add(:STORMDRAIN,
|
||||
proc { |ability,mods,user,target,move,type|
|
||||
mods[BASE_ACC] = 0 if type == :WATER
|
||||
mods[:base_accuracy] = 0 if type == :WATER
|
||||
}
|
||||
)
|
||||
|
||||
BattleHandlers::AccuracyCalcTargetAbility.add(:TANGLEDFEET,
|
||||
proc { |ability,mods,user,target,move,type|
|
||||
mods[ACC_MULT] /= 2 if target.effects[PBEffects::Confusion]>0
|
||||
mods[:accuracy_multiplier] /= 2 if target.effects[PBEffects::Confusion] > 0
|
||||
}
|
||||
)
|
||||
|
||||
BattleHandlers::AccuracyCalcTargetAbility.add(:UNAWARE,
|
||||
proc { |ability,mods,user,target,move,type|
|
||||
mods[ACC_STAGE] = 0 if move.damagingMove?
|
||||
mods[:accuracy_stage] = 0 if move.damagingMove?
|
||||
}
|
||||
)
|
||||
|
||||
BattleHandlers::AccuracyCalcTargetAbility.add(:WONDERSKIN,
|
||||
proc { |ability,mods,user,target,move,type|
|
||||
if move.statusMove? && user.opposes?(target)
|
||||
mods[BASE_ACC] = 0 if mods[BASE_ACC]>50
|
||||
mods[:base_accuracy] = 0 if mods[:base_accuracy] > 50
|
||||
end
|
||||
}
|
||||
)
|
||||
@@ -876,7 +876,7 @@ BattleHandlers::AccuracyCalcTargetAbility.add(:WONDERSKIN,
|
||||
|
||||
BattleHandlers::DamageCalcUserAbility.add(:AERILATE,
|
||||
proc { |ability,user,target,move,mults,baseDmg,type|
|
||||
mults[BASE_DMG_MULT] *= 1.2 if move.powerBoost
|
||||
mults[:base_damage_multiplier] *= 1.2 if move.powerBoost
|
||||
}
|
||||
)
|
||||
|
||||
@@ -887,7 +887,7 @@ BattleHandlers::DamageCalcUserAbility.add(:ANALYTIC,
|
||||
if (target.battle.choices[target.index][0]!=:UseMove &&
|
||||
target.battle.choices[target.index][0]!=:Shift) ||
|
||||
target.movedThisRound?
|
||||
mults[BASE_DMG_MULT] *= 1.3
|
||||
mults[:base_damage_multiplier] *= 1.3
|
||||
end
|
||||
}
|
||||
)
|
||||
@@ -895,21 +895,21 @@ BattleHandlers::DamageCalcUserAbility.add(:ANALYTIC,
|
||||
BattleHandlers::DamageCalcUserAbility.add(:BLAZE,
|
||||
proc { |ability,user,target,move,mults,baseDmg,type|
|
||||
if user.hp <= user.totalhp / 3 && type == :FIRE
|
||||
mults[ATK_MULT] *= 1.5
|
||||
mults[:attack_multiplier] *= 1.5
|
||||
end
|
||||
}
|
||||
)
|
||||
|
||||
BattleHandlers::DamageCalcUserAbility.add(:DEFEATIST,
|
||||
proc { |ability,user,target,move,mults,baseDmg,type|
|
||||
mults[ATK_MULT] /= 2 if user.hp<=user.totalhp/2
|
||||
mults[:attack_multiplier] /= 2 if user.hp <= user.totalhp / 2
|
||||
}
|
||||
)
|
||||
|
||||
BattleHandlers::DamageCalcUserAbility.add(:FLAREBOOST,
|
||||
proc { |ability,user,target,move,mults,baseDmg,type|
|
||||
if user.burned? && move.specialMove?
|
||||
mults[BASE_DMG_MULT] *= 1.5
|
||||
mults[:base_damage_multiplier] *= 1.5
|
||||
end
|
||||
}
|
||||
)
|
||||
@@ -917,7 +917,7 @@ BattleHandlers::DamageCalcUserAbility.add(:FLAREBOOST,
|
||||
BattleHandlers::DamageCalcUserAbility.add(:FLASHFIRE,
|
||||
proc { |ability,user,target,move,mults,baseDmg,type|
|
||||
if user.effects[PBEffects::FlashFire] && type == :FIRE
|
||||
mults[ATK_MULT] *= 1.5
|
||||
mults[:attack_multiplier] *= 1.5
|
||||
end
|
||||
}
|
||||
)
|
||||
@@ -926,7 +926,7 @@ BattleHandlers::DamageCalcUserAbility.add(:FLOWERGIFT,
|
||||
proc { |ability,user,target,move,mults,baseDmg,type|
|
||||
w = user.battle.pbWeather
|
||||
if move.physicalMove? && (w==PBWeather::Sun || w==PBWeather::HarshSun)
|
||||
mults[ATK_MULT] *= 1.5
|
||||
mults[:attack_multiplier] *= 1.5
|
||||
end
|
||||
}
|
||||
)
|
||||
@@ -934,14 +934,14 @@ BattleHandlers::DamageCalcUserAbility.add(:FLOWERGIFT,
|
||||
BattleHandlers::DamageCalcUserAbility.add(:GUTS,
|
||||
proc { |ability,user,target,move,mults,baseDmg,type|
|
||||
if user.pbHasAnyStatus? && move.physicalMove?
|
||||
mults[ATK_MULT] *= 1.5
|
||||
mults[:attack_multiplier] *= 1.5
|
||||
end
|
||||
}
|
||||
)
|
||||
|
||||
BattleHandlers::DamageCalcUserAbility.add(:HUGEPOWER,
|
||||
proc { |ability,user,target,move,mults,baseDmg,type|
|
||||
mults[ATK_MULT] *= 2 if move.physicalMove?
|
||||
mults[:attack_multiplier] *= 2 if move.physicalMove?
|
||||
}
|
||||
)
|
||||
|
||||
@@ -949,19 +949,19 @@ BattleHandlers::DamageCalcUserAbility.copy(:HUGEPOWER,:PUREPOWER)
|
||||
|
||||
BattleHandlers::DamageCalcUserAbility.add(:HUSTLE,
|
||||
proc { |ability,user,target,move,mults,baseDmg,type|
|
||||
mults[ATK_MULT] *= 1.5 if move.physicalMove?
|
||||
mults[:attack_multiplier] *= 1.5 if move.physicalMove?
|
||||
}
|
||||
)
|
||||
|
||||
BattleHandlers::DamageCalcUserAbility.add(:IRONFIST,
|
||||
proc { |ability,user,target,move,mults,baseDmg,type|
|
||||
mults[BASE_DMG_MULT] *= 1.2 if move.punchingMove?
|
||||
mults[:base_damage_multiplier] *= 1.2 if move.punchingMove?
|
||||
}
|
||||
)
|
||||
|
||||
BattleHandlers::DamageCalcUserAbility.add(:MEGALAUNCHER,
|
||||
proc { |ability,user,target,move,mults,baseDmg,type|
|
||||
mults[BASE_DMG_MULT] *= 1.5 if move.pulseMove?
|
||||
mults[:base_damage_multiplier] *= 1.5 if move.pulseMove?
|
||||
}
|
||||
)
|
||||
|
||||
@@ -970,7 +970,7 @@ BattleHandlers::DamageCalcUserAbility.add(:MINUS,
|
||||
next if !move.specialMove?
|
||||
user.eachAlly do |b|
|
||||
next if !b.hasActiveAbility?([:MINUS, :PLUS])
|
||||
mults[ATK_MULT] *= 1.5
|
||||
mults[:attack_multiplier] *= 1.5
|
||||
break
|
||||
end
|
||||
}
|
||||
@@ -981,7 +981,7 @@ BattleHandlers::DamageCalcUserAbility.copy(:MINUS,:PLUS)
|
||||
BattleHandlers::DamageCalcUserAbility.add(:NEUROFORCE,
|
||||
proc { |ability,user,target,move,mults,baseDmg,type|
|
||||
if PBTypeEffectiveness.superEffective?(target.damageState.typeMod)
|
||||
mults[FINAL_DMG_MULT] *= 1.25
|
||||
mults[:final_damage_multiplier] *= 1.25
|
||||
end
|
||||
}
|
||||
)
|
||||
@@ -989,14 +989,14 @@ BattleHandlers::DamageCalcUserAbility.add(:NEUROFORCE,
|
||||
BattleHandlers::DamageCalcUserAbility.add(:OVERGROW,
|
||||
proc { |ability,user,target,move,mults,baseDmg,type|
|
||||
if user.hp <= user.totalhp / 3 && type == :GRASS
|
||||
mults[ATK_MULT] *= 1.5
|
||||
mults[:attack_multiplier] *= 1.5
|
||||
end
|
||||
}
|
||||
)
|
||||
|
||||
BattleHandlers::DamageCalcUserAbility.add(:RECKLESS,
|
||||
proc { |ability,user,target,move,mults,baseDmg,type|
|
||||
mults[BASE_DMG_MULT] *= 1.2 if move.recoilMove?
|
||||
mults[:base_damage_multiplier] *= 1.2 if move.recoilMove?
|
||||
}
|
||||
)
|
||||
|
||||
@@ -1004,9 +1004,9 @@ BattleHandlers::DamageCalcUserAbility.add(:RIVALRY,
|
||||
proc { |ability,user,target,move,mults,baseDmg,type|
|
||||
if user.gender!=2 && target.gender!=2
|
||||
if user.gender==target.gender
|
||||
mults[BASE_DMG_MULT] *= 1.25
|
||||
mults[:base_damage_multiplier] *= 1.25
|
||||
else
|
||||
mults[BASE_DMG_MULT] *= 0.75
|
||||
mults[:base_damage_multiplier] *= 0.75
|
||||
end
|
||||
end
|
||||
}
|
||||
@@ -1016,20 +1016,20 @@ BattleHandlers::DamageCalcUserAbility.add(:SANDFORCE,
|
||||
proc { |ability,user,target,move,mults,baseDmg,type|
|
||||
if user.battle.pbWeather==PBWeather::Sandstorm &&
|
||||
[:ROCK, :GROUND, :STEEL].include?(type)
|
||||
mults[BASE_DMG_MULT] *= 1.3
|
||||
mults[:base_damage_multiplier] *= 1.3
|
||||
end
|
||||
}
|
||||
)
|
||||
|
||||
BattleHandlers::DamageCalcUserAbility.add(:SHEERFORCE,
|
||||
proc { |ability,user,target,move,mults,baseDmg,type|
|
||||
mults[BASE_DMG_MULT] *= 1.3 if move.addlEffect>0
|
||||
mults[:base_damage_multiplier] *= 1.3 if move.addlEffect > 0
|
||||
}
|
||||
)
|
||||
|
||||
BattleHandlers::DamageCalcUserAbility.add(:SLOWSTART,
|
||||
proc { |ability,user,target,move,mults,baseDmg,type|
|
||||
mults[ATK_MULT] /= 2 if user.effects[PBEffects::SlowStart]>0 && move.physicalMove?
|
||||
mults[:attack_multiplier] /= 2 if user.effects[PBEffects::SlowStart] > 0 && move.physicalMove?
|
||||
}
|
||||
)
|
||||
|
||||
@@ -1037,7 +1037,7 @@ BattleHandlers::DamageCalcUserAbility.add(:SOLARPOWER,
|
||||
proc { |ability,user,target,move,mults,baseDmg,type|
|
||||
w = user.battle.pbWeather
|
||||
if move.specialMove? && (w == PBWeather::Sun || w == PBWeather::HarshSun)
|
||||
mults[ATK_MULT] *= 1.5
|
||||
mults[:attack_multiplier] *= 1.5
|
||||
end
|
||||
}
|
||||
)
|
||||
@@ -1045,33 +1045,33 @@ BattleHandlers::DamageCalcUserAbility.add(:SOLARPOWER,
|
||||
BattleHandlers::DamageCalcUserAbility.add(:SNIPER,
|
||||
proc { |ability,user,target,move,mults,baseDmg,type|
|
||||
if target.damageState.critical
|
||||
mults[FINAL_DMG_MULT] *= 1.5
|
||||
mults[:final_damage_multiplier] *= 1.5
|
||||
end
|
||||
}
|
||||
)
|
||||
|
||||
BattleHandlers::DamageCalcUserAbility.add(:STAKEOUT,
|
||||
proc { |ability,user,target,move,mults,baseDmg,type|
|
||||
mults[ATK_MULT] *= 2 if target.battle.choices[target.index][0]==:SwitchOut
|
||||
mults[:attack_multiplier] *= 2 if target.battle.choices[target.index][0] == :SwitchOut
|
||||
}
|
||||
)
|
||||
|
||||
BattleHandlers::DamageCalcUserAbility.add(:STEELWORKER,
|
||||
proc { |ability,user,target,move,mults,baseDmg,type|
|
||||
mults[ATK_MULT] *= 1.5 if type == :STEEL
|
||||
mults[:attack_multiplier] *= 1.5 if type == :STEEL
|
||||
}
|
||||
)
|
||||
|
||||
BattleHandlers::DamageCalcUserAbility.add(:STRONGJAW,
|
||||
proc { |ability,user,target,move,mults,baseDmg,type|
|
||||
mults[BASE_DMG_MULT] *= 1.5 if move.bitingMove?
|
||||
mults[:base_damage_multiplier] *= 1.5 if move.bitingMove?
|
||||
}
|
||||
)
|
||||
|
||||
BattleHandlers::DamageCalcUserAbility.add(:SWARM,
|
||||
proc { |ability,user,target,move,mults,baseDmg,type|
|
||||
if user.hp <= user.totalhp / 3 && type == :BUG
|
||||
mults[ATK_MULT] *= 1.5
|
||||
mults[:attack_multiplier] *= 1.5
|
||||
end
|
||||
}
|
||||
)
|
||||
@@ -1079,43 +1079,43 @@ BattleHandlers::DamageCalcUserAbility.add(:SWARM,
|
||||
BattleHandlers::DamageCalcUserAbility.add(:TECHNICIAN,
|
||||
proc { |ability,user,target,move,mults,baseDmg,type|
|
||||
if user.index != target.index && move && move.id != :STRUGGLE &&
|
||||
baseDmg*mults[BASE_DMG_MULT]<=60
|
||||
mults[BASE_DMG_MULT] *= 1.5
|
||||
baseDmg * mults[:base_damage_multiplier] <= 60
|
||||
mults[:base_damage_multiplier] *= 1.5
|
||||
end
|
||||
}
|
||||
)
|
||||
|
||||
BattleHandlers::DamageCalcUserAbility.add(:TINTEDLENS,
|
||||
proc { |ability,user,target,move,mults,baseDmg,type|
|
||||
mults[FINAL_DMG_MULT] *= 2 if PBTypeEffectiveness.resistant?(target.damageState.typeMod)
|
||||
mults[:final_damage_multiplier] *= 2 if PBTypeEffectiveness.resistant?(target.damageState.typeMod)
|
||||
}
|
||||
)
|
||||
|
||||
BattleHandlers::DamageCalcUserAbility.add(:TORRENT,
|
||||
proc { |ability,user,target,move,mults,baseDmg,type|
|
||||
if user.hp <= user.totalhp / 3 && type == :WATER
|
||||
mults[ATK_MULT] *= 1.5
|
||||
mults[:attack_multiplier] *= 1.5
|
||||
end
|
||||
}
|
||||
)
|
||||
|
||||
BattleHandlers::DamageCalcUserAbility.add(:TOUGHCLAWS,
|
||||
proc { |ability,user,target,move,mults,baseDmg,type|
|
||||
mults[BASE_DMG_MULT] *= 4/3.0 if move.contactMove?
|
||||
mults[:base_damage_multiplier] *= 4 / 3.0 if move.contactMove?
|
||||
}
|
||||
)
|
||||
|
||||
BattleHandlers::DamageCalcUserAbility.add(:TOXICBOOST,
|
||||
proc { |ability,user,target,move,mults,baseDmg,type|
|
||||
if user.poisoned? && move.physicalMove?
|
||||
mults[BASE_DMG_MULT] *= 1.5
|
||||
mults[:base_damage_multiplier] *= 1.5
|
||||
end
|
||||
}
|
||||
)
|
||||
|
||||
BattleHandlers::DamageCalcUserAbility.add(:WATERBUBBLE,
|
||||
proc { |ability,user,target,move,mults,baseDmg,type|
|
||||
mults[ATK_MULT] *= 2 if type == :WATER
|
||||
mults[:attack_multiplier] *= 2 if type == :WATER
|
||||
}
|
||||
)
|
||||
|
||||
@@ -1126,7 +1126,7 @@ BattleHandlers::DamageCalcUserAbility.add(:WATERBUBBLE,
|
||||
BattleHandlers::DamageCalcUserAllyAbility.add(:BATTERY,
|
||||
proc { |ability,user,target,move,mults,baseDmg,type|
|
||||
next if !move.specialMove?
|
||||
mults[FINAL_DMG_MULT] *= 1.3
|
||||
mults[:final_damage_multiplier] *= 1.3
|
||||
}
|
||||
)
|
||||
|
||||
@@ -1134,7 +1134,7 @@ BattleHandlers::DamageCalcUserAllyAbility.add(:FLOWERGIFT,
|
||||
proc { |ability,user,target,move,mults,baseDmg,type|
|
||||
w = user.battle.pbWeather
|
||||
if move.physicalMove? && (w == PBWeather::Sun || w == PBWeather::HarshSun)
|
||||
mults[ATK_MULT] *= 1.5
|
||||
mults[:attack_multiplier] *= 1.5
|
||||
end
|
||||
}
|
||||
)
|
||||
@@ -1145,14 +1145,14 @@ BattleHandlers::DamageCalcUserAllyAbility.add(:FLOWERGIFT,
|
||||
|
||||
BattleHandlers::DamageCalcTargetAbility.add(:DRYSKIN,
|
||||
proc { |ability,user,target,move,mults,baseDmg,type|
|
||||
mults[BASE_DMG_MULT] *= 1.25 if type == :FIRE
|
||||
mults[:base_damage_multiplier] *= 1.25 if type == :FIRE
|
||||
}
|
||||
)
|
||||
|
||||
BattleHandlers::DamageCalcTargetAbility.add(:FILTER,
|
||||
proc { |ability,user,target,move,mults,baseDmg,type|
|
||||
if PBTypeEffectiveness.superEffective?(target.damageState.typeMod)
|
||||
mults[FINAL_DMG_MULT] *= 0.75
|
||||
mults[:final_damage_multiplier] *= 0.75
|
||||
end
|
||||
}
|
||||
)
|
||||
@@ -1163,61 +1163,61 @@ BattleHandlers::DamageCalcTargetAbility.add(:FLOWERGIFT,
|
||||
proc { |ability,user,target,move,mults,baseDmg,type|
|
||||
w = user.battle.pbWeather
|
||||
if move.specialMove? && (w == PBWeather::Sun || w == PBWeather::HarshSun)
|
||||
mults[DEF_MULT] *= 1.5
|
||||
mults[:defense_multiplier] *= 1.5
|
||||
end
|
||||
}
|
||||
)
|
||||
|
||||
BattleHandlers::DamageCalcTargetAbility.add(:FLUFFY,
|
||||
proc { |ability,user,target,move,mults,baseDmg,type|
|
||||
mults[FINAL_DMG_MULT] *= 2 if move.calcType == :FIRE
|
||||
mults[FINAL_DMG_MULT] /= 2 if move.contactMove?
|
||||
mults[:final_damage_multiplier] *= 2 if move.calcType == :FIRE
|
||||
mults[:final_damage_multiplier] /= 2 if move.contactMove?
|
||||
}
|
||||
)
|
||||
|
||||
BattleHandlers::DamageCalcTargetAbility.add(:FURCOAT,
|
||||
proc { |ability,user,target,move,mults,baseDmg,type|
|
||||
mults[DEF_MULT] *= 2 if move.physicalMove? || move.function=="122" # Psyshock
|
||||
mults[:defense_multiplier] *= 2 if move.physicalMove? || move.function == "122" # Psyshock
|
||||
}
|
||||
)
|
||||
|
||||
BattleHandlers::DamageCalcTargetAbility.add(:GRASSPELT,
|
||||
proc { |ability,user,target,move,mults,baseDmg,type|
|
||||
if user.battle.field.terrain == PBBattleTerrains::Grassy
|
||||
mults[DEF_MULT] *= 1.5
|
||||
mults[:defense_multiplier] *= 1.5
|
||||
end
|
||||
}
|
||||
)
|
||||
|
||||
BattleHandlers::DamageCalcTargetAbility.add(:HEATPROOF,
|
||||
proc { |ability,user,target,move,mults,baseDmg,type|
|
||||
mults[BASE_DMG_MULT] /= 2 if type == :FIRE
|
||||
mults[:base_damage_multiplier] /= 2 if type == :FIRE
|
||||
}
|
||||
)
|
||||
|
||||
BattleHandlers::DamageCalcTargetAbility.add(:MARVELSCALE,
|
||||
proc { |ability,user,target,move,mults,baseDmg,type|
|
||||
if target.pbHasAnyStatus? && move.physicalMove?
|
||||
mults[DEF_MULT] *= 1.5
|
||||
mults[:defense_multiplier] *= 1.5
|
||||
end
|
||||
}
|
||||
)
|
||||
|
||||
BattleHandlers::DamageCalcTargetAbility.add(:MULTISCALE,
|
||||
proc { |ability,user,target,move,mults,baseDmg,type|
|
||||
mults[FINAL_DMG_MULT] /= 2 if target.hp==target.totalhp
|
||||
mults[:final_damage_multiplier] /= 2 if target.hp == target.totalhp
|
||||
}
|
||||
)
|
||||
|
||||
BattleHandlers::DamageCalcTargetAbility.add(:THICKFAT,
|
||||
proc { |ability,user,target,move,mults,baseDmg,type|
|
||||
mults[BASE_DMG_MULT] /= 2 if type == :FIRE || type == :ICE
|
||||
mults[:base_damage_multiplier] /= 2 if type == :FIRE || type == :ICE
|
||||
}
|
||||
)
|
||||
|
||||
BattleHandlers::DamageCalcTargetAbility.add(:WATERBUBBLE,
|
||||
proc { |ability,user,target,move,mults,baseDmg,type|
|
||||
mults[FINAL_DMG_MULT] /= 2 if type == :FIRE
|
||||
mults[:final_damage_multiplier] /= 2 if type == :FIRE
|
||||
}
|
||||
)
|
||||
|
||||
@@ -1228,7 +1228,7 @@ BattleHandlers::DamageCalcTargetAbility.add(:WATERBUBBLE,
|
||||
BattleHandlers::DamageCalcTargetAbilityNonIgnorable.add(:PRISMARMOR,
|
||||
proc { |ability,user,target,move,mults,baseDmg,type|
|
||||
if PBTypeEffectiveness.superEffective?(target.damageState.typeMod)
|
||||
mults[FINAL_DMG_MULT] *= 0.75
|
||||
mults[:final_damage_multiplier] *= 0.75
|
||||
end
|
||||
}
|
||||
)
|
||||
@@ -1236,7 +1236,7 @@ BattleHandlers::DamageCalcTargetAbilityNonIgnorable.add(:PRISMARMOR,
|
||||
BattleHandlers::DamageCalcTargetAbilityNonIgnorable.add(:SHADOWSHIELD,
|
||||
proc { |ability,user,target,move,mults,baseDmg,type|
|
||||
if target.hp==target.totalhp
|
||||
mults[FINAL_DMG_MULT] /= 2
|
||||
mults[:final_damage_multiplier] /= 2
|
||||
end
|
||||
}
|
||||
)
|
||||
@@ -1249,14 +1249,14 @@ BattleHandlers::DamageCalcTargetAllyAbility.add(:FLOWERGIFT,
|
||||
proc { |ability,user,target,move,mults,baseDmg,type|
|
||||
w = user.battle.pbWeather
|
||||
if move.specialMove? && (w == PBWeather::Sun || w == PBWeather::HarshSun)
|
||||
mults[DEF_MULT] *= 1.5
|
||||
mults[:defense_multiplier] *= 1.5
|
||||
end
|
||||
}
|
||||
)
|
||||
|
||||
BattleHandlers::DamageCalcTargetAllyAbility.add(:FRIENDGUARD,
|
||||
proc { |ability,user,target,move,mults,baseDmg,type|
|
||||
mults[FINAL_DMG_MULT] *= 0.75
|
||||
mults[:final_damage_multiplier] *= 0.75
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@@ -412,7 +412,7 @@ BattleHandlers::PriorityBracketUseItem.add(:QUICKCLAW,
|
||||
|
||||
BattleHandlers::AccuracyCalcUserItem.add(:WIDELENS,
|
||||
proc { |item,mods,user,target,move,type|
|
||||
mods[ACC_MULT] *= 1.1
|
||||
mods[:accuracy_multiplier] *= 1.1
|
||||
}
|
||||
)
|
||||
|
||||
@@ -421,7 +421,7 @@ BattleHandlers::AccuracyCalcUserItem.add(:ZOOMLENS,
|
||||
if (target.battle.choices[target.index][0]!=:UseMove &&
|
||||
target.battle.choices[target.index][0]!=:Shift) ||
|
||||
target.movedThisRound?
|
||||
mods[ACC_MULT] *= 1.2
|
||||
mods[:accuracy_multiplier] *= 1.2
|
||||
end
|
||||
}
|
||||
)
|
||||
@@ -432,7 +432,7 @@ BattleHandlers::AccuracyCalcUserItem.add(:ZOOMLENS,
|
||||
|
||||
BattleHandlers::AccuracyCalcTargetItem.add(:BRIGHTPOWDER,
|
||||
proc { |item,mods,user,target,move,type|
|
||||
mods[ACC_MULT] *= 0.9
|
||||
mods[:accuracy_multiplier] *= 0.9
|
||||
}
|
||||
)
|
||||
|
||||
@@ -445,14 +445,14 @@ BattleHandlers::AccuracyCalcTargetItem.copy(:BRIGHTPOWDER,:LAXINCENSE)
|
||||
BattleHandlers::DamageCalcUserItem.add(:ADAMANTORB,
|
||||
proc { |item,user,target,move,mults,baseDmg,type|
|
||||
if user.isSpecies?(:DIALGA) && (type == :DRAGON || type == :STEEL)
|
||||
mults[BASE_DMG_MULT] *= 1.2
|
||||
mults[:base_damage_multiplier] *= 1.2
|
||||
end
|
||||
}
|
||||
)
|
||||
|
||||
BattleHandlers::DamageCalcUserItem.add(:BLACKBELT,
|
||||
proc { |item,user,target,move,mults,baseDmg,type|
|
||||
mults[BASE_DMG_MULT] *= 1.2 if type == :FIGHTING
|
||||
mults[:base_damage_multiplier] *= 1.2 if type == :FIGHTING
|
||||
}
|
||||
)
|
||||
|
||||
@@ -460,7 +460,7 @@ BattleHandlers::DamageCalcUserItem.copy(:BLACKBELT,:FISTPLATE)
|
||||
|
||||
BattleHandlers::DamageCalcUserItem.add(:BLACKGLASSES,
|
||||
proc { |item,user,target,move,mults,baseDmg,type|
|
||||
mults[BASE_DMG_MULT] *= 1.2 if type == :DARK
|
||||
mults[:base_damage_multiplier] *= 1.2 if type == :DARK
|
||||
}
|
||||
)
|
||||
|
||||
@@ -474,7 +474,7 @@ BattleHandlers::DamageCalcUserItem.add(:BUGGEM,
|
||||
|
||||
BattleHandlers::DamageCalcUserItem.add(:CHARCOAL,
|
||||
proc { |item,user,target,move,mults,baseDmg,type|
|
||||
mults[BASE_DMG_MULT] *= 1.2 if type == :FIRE
|
||||
mults[:base_damage_multiplier] *= 1.2 if type == :FIRE
|
||||
}
|
||||
)
|
||||
|
||||
@@ -482,13 +482,13 @@ BattleHandlers::DamageCalcUserItem.copy(:CHARCOAL,:FLAMEPLATE)
|
||||
|
||||
BattleHandlers::DamageCalcUserItem.add(:CHOICEBAND,
|
||||
proc { |item,user,target,move,mults,baseDmg,type|
|
||||
mults[BASE_DMG_MULT] *= 1.5 if move.physicalMove?
|
||||
mults[:base_damage_multiplier] *= 1.5 if move.physicalMove?
|
||||
}
|
||||
)
|
||||
|
||||
BattleHandlers::DamageCalcUserItem.add(:CHOICESPECS,
|
||||
proc { |item,user,target,move,mults,baseDmg,type|
|
||||
mults[BASE_DMG_MULT] *= 1.5 if move.specialMove?
|
||||
mults[:base_damage_multiplier] *= 1.5 if move.specialMove?
|
||||
}
|
||||
)
|
||||
|
||||
@@ -501,14 +501,14 @@ BattleHandlers::DamageCalcUserItem.add(:DARKGEM,
|
||||
BattleHandlers::DamageCalcUserItem.add(:DEEPSEATOOTH,
|
||||
proc { |item,user,target,move,mults,baseDmg,type|
|
||||
if user.isSpecies?(:CLAMPERL) && move.specialMove?
|
||||
mults[ATK_MULT] *= 2
|
||||
mults[:attack_multiplier] *= 2
|
||||
end
|
||||
}
|
||||
)
|
||||
|
||||
BattleHandlers::DamageCalcUserItem.add(:DRAGONFANG,
|
||||
proc { |item,user,target,move,mults,baseDmg,type|
|
||||
mults[BASE_DMG_MULT] *= 1.2 if type == :DRAGON
|
||||
mults[:base_damage_multiplier] *= 1.2 if type == :DRAGON
|
||||
}
|
||||
)
|
||||
|
||||
@@ -529,7 +529,7 @@ BattleHandlers::DamageCalcUserItem.add(:ELECTRICGEM,
|
||||
BattleHandlers::DamageCalcUserItem.add(:EXPERTBELT,
|
||||
proc { |item,user,target,move,mults,baseDmg,type|
|
||||
if PBTypeEffectiveness.superEffective?(target.damageState.typeMod)
|
||||
mults[FINAL_DMG_MULT] *= 1.2
|
||||
mults[:final_damage_multiplier] *= 1.2
|
||||
end
|
||||
}
|
||||
)
|
||||
@@ -573,7 +573,7 @@ BattleHandlers::DamageCalcUserItem.add(:GRASSGEM,
|
||||
BattleHandlers::DamageCalcUserItem.add(:GRISEOUSORB,
|
||||
proc { |item,user,target,move,mults,baseDmg,type|
|
||||
if user.isSpecies?(:GIRATINA) && (type == :DRAGON || type == :GHOST)
|
||||
mults[BASE_DMG_MULT] *= 1.2
|
||||
mults[:base_damage_multiplier] *= 1.2
|
||||
end
|
||||
}
|
||||
)
|
||||
@@ -586,7 +586,7 @@ BattleHandlers::DamageCalcUserItem.add(:GROUNDGEM,
|
||||
|
||||
BattleHandlers::DamageCalcUserItem.add(:HARDSTONE,
|
||||
proc { |item,user,target,move,mults,baseDmg,type|
|
||||
mults[BASE_DMG_MULT] *= 1.2 if type == :ROCK
|
||||
mults[:base_damage_multiplier] *= 1.2 if type == :ROCK
|
||||
}
|
||||
)
|
||||
|
||||
@@ -601,7 +601,7 @@ BattleHandlers::DamageCalcUserItem.add(:ICEGEM,
|
||||
BattleHandlers::DamageCalcUserItem.add(:LIFEORB,
|
||||
proc { |item,user,target,move,mults,baseDmg,type|
|
||||
if !move.is_a?(PokeBattle_Confusion)
|
||||
mults[FINAL_DMG_MULT] *= 1.3
|
||||
mults[:final_damage_multiplier] *= 1.3
|
||||
end
|
||||
}
|
||||
)
|
||||
@@ -609,7 +609,7 @@ BattleHandlers::DamageCalcUserItem.add(:LIFEORB,
|
||||
BattleHandlers::DamageCalcUserItem.add(:LIGHTBALL,
|
||||
proc { |item,user,target,move,mults,baseDmg,type|
|
||||
if user.isSpecies?(:PIKACHU)
|
||||
mults[ATK_MULT] *= 2
|
||||
mults[:attack_multiplier] *= 2
|
||||
end
|
||||
}
|
||||
)
|
||||
@@ -617,14 +617,14 @@ BattleHandlers::DamageCalcUserItem.add(:LIGHTBALL,
|
||||
BattleHandlers::DamageCalcUserItem.add(:LUSTROUSORB,
|
||||
proc { |item,user,target,move,mults,baseDmg,type|
|
||||
if user.isSpecies?(:PALKIA) && (type == :DRAGON || type == :WATER)
|
||||
mults[BASE_DMG_MULT] *= 1.2
|
||||
mults[:base_damage_multiplier] *= 1.2
|
||||
end
|
||||
}
|
||||
)
|
||||
|
||||
BattleHandlers::DamageCalcUserItem.add(:MAGNET,
|
||||
proc { |item,user,target,move,mults,baseDmg,type|
|
||||
mults[BASE_DMG_MULT] *= 1.2 if type == :ELECTRIC
|
||||
mults[:base_damage_multiplier] *= 1.2 if type == :ELECTRIC
|
||||
}
|
||||
)
|
||||
|
||||
@@ -632,7 +632,7 @@ BattleHandlers::DamageCalcUserItem.copy(:MAGNET,:ZAPPLATE)
|
||||
|
||||
BattleHandlers::DamageCalcUserItem.add(:METALCOAT,
|
||||
proc { |item,user,target,move,mults,baseDmg,type|
|
||||
mults[BASE_DMG_MULT] *= 1.2 if type == :STEEL
|
||||
mults[:base_damage_multiplier] *= 1.2 if type == :STEEL
|
||||
}
|
||||
)
|
||||
|
||||
@@ -641,13 +641,13 @@ BattleHandlers::DamageCalcUserItem.copy(:METALCOAT,:IRONPLATE)
|
||||
BattleHandlers::DamageCalcUserItem.add(:METRONOME,
|
||||
proc { |item,user,target,move,mults,baseDmg,type|
|
||||
met = 1 + 0.2 * [user.effects[PBEffects::Metronome], 5].min
|
||||
mults[FINAL_DMG_MULT] *= met
|
||||
mults[:final_damage_multiplier] *= met
|
||||
}
|
||||
)
|
||||
|
||||
BattleHandlers::DamageCalcUserItem.add(:MIRACLESEED,
|
||||
proc { |item,user,target,move,mults,baseDmg,type|
|
||||
mults[BASE_DMG_MULT] *= 1.2 if type == :GRASS
|
||||
mults[:base_damage_multiplier] *= 1.2 if type == :GRASS
|
||||
}
|
||||
)
|
||||
|
||||
@@ -655,13 +655,13 @@ BattleHandlers::DamageCalcUserItem.copy(:MIRACLESEED,:MEADOWPLATE,:ROSEINCENSE)
|
||||
|
||||
BattleHandlers::DamageCalcUserItem.add(:MUSCLEBAND,
|
||||
proc { |item,user,target,move,mults,baseDmg,type|
|
||||
mults[BASE_DMG_MULT] *= 1.1 if move.physicalMove?
|
||||
mults[:base_damage_multiplier] *= 1.1 if move.physicalMove?
|
||||
}
|
||||
)
|
||||
|
||||
BattleHandlers::DamageCalcUserItem.add(:MYSTICWATER,
|
||||
proc { |item,user,target,move,mults,baseDmg,type|
|
||||
mults[BASE_DMG_MULT] *= 1.2 if type == :WATER
|
||||
mults[:base_damage_multiplier] *= 1.2 if type == :WATER
|
||||
}
|
||||
)
|
||||
|
||||
@@ -669,7 +669,7 @@ BattleHandlers::DamageCalcUserItem.copy(:MYSTICWATER,:SPLASHPLATE,:SEAINCENSE,:W
|
||||
|
||||
BattleHandlers::DamageCalcUserItem.add(:NEVERMELTICE,
|
||||
proc { |item,user,target,move,mults,baseDmg,type|
|
||||
mults[BASE_DMG_MULT] *= 1.2 if type == :ICE
|
||||
mults[:base_damage_multiplier] *= 1.2 if type == :ICE
|
||||
}
|
||||
)
|
||||
|
||||
@@ -683,13 +683,13 @@ BattleHandlers::DamageCalcUserItem.add(:NORMALGEM,
|
||||
|
||||
BattleHandlers::DamageCalcUserItem.add(:PIXIEPLATE,
|
||||
proc { |item,user,target,move,mults,baseDmg,type|
|
||||
mults[BASE_DMG_MULT] *= 1.2 if type == :FAIRY
|
||||
mults[:base_damage_multiplier] *= 1.2 if type == :FAIRY
|
||||
}
|
||||
)
|
||||
|
||||
BattleHandlers::DamageCalcUserItem.add(:POISONBARB,
|
||||
proc { |item,user,target,move,mults,baseDmg,type|
|
||||
mults[BASE_DMG_MULT] *= 1.2 if type == :POISON
|
||||
mults[:base_damage_multiplier] *= 1.2 if type == :POISON
|
||||
}
|
||||
)
|
||||
|
||||
@@ -715,7 +715,7 @@ BattleHandlers::DamageCalcUserItem.add(:ROCKGEM,
|
||||
|
||||
BattleHandlers::DamageCalcUserItem.add(:SHARPBEAK,
|
||||
proc { |item,user,target,move,mults,baseDmg,type|
|
||||
mults[BASE_DMG_MULT] *= 1.2 if type == :FLYING
|
||||
mults[:base_damage_multiplier] *= 1.2 if type == :FLYING
|
||||
}
|
||||
)
|
||||
|
||||
@@ -723,13 +723,13 @@ BattleHandlers::DamageCalcUserItem.copy(:SHARPBEAK,:SKYPLATE)
|
||||
|
||||
BattleHandlers::DamageCalcUserItem.add(:SILKSCARF,
|
||||
proc { |item,user,target,move,mults,baseDmg,type|
|
||||
mults[BASE_DMG_MULT] *= 1.2 if type == :NORMAL
|
||||
mults[:base_damage_multiplier] *= 1.2 if type == :NORMAL
|
||||
}
|
||||
)
|
||||
|
||||
BattleHandlers::DamageCalcUserItem.add(:SILVERPOWDER,
|
||||
proc { |item,user,target,move,mults,baseDmg,type|
|
||||
mults[BASE_DMG_MULT] *= 1.2 if type == :BUG
|
||||
mults[:base_damage_multiplier] *= 1.2 if type == :BUG
|
||||
}
|
||||
)
|
||||
|
||||
@@ -737,7 +737,7 @@ BattleHandlers::DamageCalcUserItem.copy(:SILVERPOWDER,:INSECTPLATE)
|
||||
|
||||
BattleHandlers::DamageCalcUserItem.add(:SOFTSAND,
|
||||
proc { |item,user,target,move,mults,baseDmg,type|
|
||||
mults[BASE_DMG_MULT] *= 1.2 if type == :GROUND
|
||||
mults[:base_damage_multiplier] *= 1.2 if type == :GROUND
|
||||
}
|
||||
)
|
||||
|
||||
@@ -747,10 +747,10 @@ BattleHandlers::DamageCalcUserItem.add(:SOULDEW,
|
||||
proc { |item,user,target,move,mults,baseDmg,type|
|
||||
next if !user.isSpecies?(:LATIAS) && !user.isSpecies?(:LATIOS)
|
||||
if SOUL_DEW_POWERS_UP_TYPES
|
||||
mults[FINAL_DMG_MULT] *= 1.2 if type == :PSYCHIC || type == :DRAGON
|
||||
mults[:final_damage_multiplier] *= 1.2 if type == :PSYCHIC || type == :DRAGON
|
||||
else
|
||||
if move.specialMove? && !user.battle.rules["souldewclause"]
|
||||
mults[ATK_MULT] *= 1.5
|
||||
mults[:attack_multiplier] *= 1.5
|
||||
end
|
||||
end
|
||||
}
|
||||
@@ -758,7 +758,7 @@ BattleHandlers::DamageCalcUserItem.add(:SOULDEW,
|
||||
|
||||
BattleHandlers::DamageCalcUserItem.add(:SPELLTAG,
|
||||
proc { |item,user,target,move,mults,baseDmg,type|
|
||||
mults[BASE_DMG_MULT] *= 1.2 if type == :GHOST
|
||||
mults[:base_damage_multiplier] *= 1.2 if type == :GHOST
|
||||
}
|
||||
)
|
||||
|
||||
@@ -773,14 +773,14 @@ BattleHandlers::DamageCalcUserItem.add(:STEELGEM,
|
||||
BattleHandlers::DamageCalcUserItem.add(:THICKCLUB,
|
||||
proc { |item,user,target,move,mults,baseDmg,type|
|
||||
if (user.isSpecies?(:CUBONE) || user.isSpecies?(:MAROWAK)) && move.physicalMove?
|
||||
mults[ATK_MULT] *= 2
|
||||
mults[:attack_multiplier] *= 2
|
||||
end
|
||||
}
|
||||
)
|
||||
|
||||
BattleHandlers::DamageCalcUserItem.add(:TWISTEDSPOON,
|
||||
proc { |item,user,target,move,mults,baseDmg,type|
|
||||
mults[BASE_DMG_MULT] *= 1.2 if type == :PSYCHIC
|
||||
mults[:base_damage_multiplier] *= 1.2 if type == :PSYCHIC
|
||||
}
|
||||
)
|
||||
|
||||
@@ -794,7 +794,7 @@ BattleHandlers::DamageCalcUserItem.add(:WATERGEM,
|
||||
|
||||
BattleHandlers::DamageCalcUserItem.add(:WISEGLASSES,
|
||||
proc { |item,user,target,move,mults,baseDmg,type|
|
||||
mults[BASE_DMG_MULT] *= 1.1 if move.specialMove?
|
||||
mults[:base_damage_multiplier] *= 1.1 if move.specialMove?
|
||||
}
|
||||
)
|
||||
|
||||
@@ -807,7 +807,7 @@ BattleHandlers::DamageCalcUserItem.add(:WISEGLASSES,
|
||||
|
||||
BattleHandlers::DamageCalcTargetItem.add(:ASSAULTVEST,
|
||||
proc { |item,user,target,move,mults,baseDmg,type|
|
||||
mults[DEF_MULT] *= 1.5 if move.specialMove?
|
||||
mults[:defense_multiplier] *= 1.5 if move.specialMove?
|
||||
}
|
||||
)
|
||||
|
||||
@@ -850,7 +850,7 @@ BattleHandlers::DamageCalcTargetItem.add(:COLBURBERRY,
|
||||
BattleHandlers::DamageCalcTargetItem.add(:DEEPSEASCALE,
|
||||
proc { |item,user,target,move,mults,baseDmg,type|
|
||||
if target.isSpecies?(:CLAMPERL) && move.specialMove?
|
||||
mults[DEF_MULT] *= 2
|
||||
mults[:defense_multiplier] *= 2
|
||||
end
|
||||
}
|
||||
)
|
||||
@@ -863,7 +863,7 @@ BattleHandlers::DamageCalcTargetItem.add(:EVIOLITE,
|
||||
# affected by Eviolite.
|
||||
evos = target.pokemon.species_data.evolutions
|
||||
if evos.any? { |e| e[1] != PBEvolution::None && !e[3] } # Not a "None", not a prevolution
|
||||
mults[DEF_MULT] *= 1.5 if evos && evos.length > 0
|
||||
mults[:defense_multiplier] *= 1.5
|
||||
end
|
||||
}
|
||||
)
|
||||
@@ -889,7 +889,7 @@ BattleHandlers::DamageCalcTargetItem.add(:KEBIABERRY,
|
||||
BattleHandlers::DamageCalcTargetItem.add(:METALPOWDER,
|
||||
proc { |item,user,target,move,mults,baseDmg,type|
|
||||
if target.isSpecies?(:DITTO) && !target.effects[PBEffects::Transform]
|
||||
mults[DEF_MULT] *= 1.5
|
||||
mults[:defense_multiplier] *= 1.5
|
||||
end
|
||||
}
|
||||
)
|
||||
@@ -935,7 +935,7 @@ BattleHandlers::DamageCalcTargetItem.add(:SOULDEW,
|
||||
next if SOUL_DEW_POWERS_UP_TYPES
|
||||
next if !target.isSpecies?(:LATIAS) && !target.isSpecies?(:LATIOS)
|
||||
if move.specialMove? && !user.battle.rules["souldewclause"]
|
||||
mults[DEF_MULT] *= 1.5
|
||||
mults[:defense_multiplier] *= 1.5
|
||||
end
|
||||
}
|
||||
)
|
||||
|
||||
@@ -130,8 +130,8 @@ def pbConvertTrainerData
|
||||
tr_type_names[t.id_number] = t.real_name
|
||||
end
|
||||
MessageTypes.setMessages(MessageTypes::TrainerTypes, tr_type_names)
|
||||
pbSaveTrainerTypes
|
||||
pbSaveTrainerBattles
|
||||
Compiler.write_trainer_types
|
||||
Compiler.write_trainers
|
||||
end
|
||||
|
||||
def pbNewTrainer(tr_type, tr_name, tr_id, savechanges = true)
|
||||
|
||||
@@ -406,7 +406,7 @@ class Pokemon
|
||||
return @moves.length
|
||||
end
|
||||
|
||||
# @param move [Integer, Symbol, String] ID of the move to check
|
||||
# @param move_id [Integer, Symbol, String] ID of the move to check
|
||||
# @return [Boolean] whether the Pokémon knows the given move
|
||||
def hasMove?(move_id)
|
||||
move_data = GameData::Move.try_get(move_id)
|
||||
@@ -503,7 +503,7 @@ class Pokemon
|
||||
@firstmoves = []
|
||||
end
|
||||
|
||||
# @param move [Integer, Symbol, String] ID of the move to check
|
||||
# @param move_id [Integer, Symbol, String] ID of the move to check
|
||||
# @return [Boolean] whether the Pokémon is compatible with the given move
|
||||
def compatibleWithMove?(move_id)
|
||||
move_data = GameData::Move.try_get(move_id)
|
||||
@@ -821,7 +821,7 @@ class Pokemon
|
||||
calcStats
|
||||
end
|
||||
|
||||
# @param species [Integer, Symbol, String] id of the species to check for
|
||||
# @param check_species [Integer, Symbol, String] id of the species to check for
|
||||
# @return [Boolean] whether this Pokémon is of the specified species
|
||||
def isSpecies?(check_species)
|
||||
return @species == check_species || @species == GameData::Species.get(check_species).species
|
||||
|
||||
@@ -167,6 +167,7 @@ class PokemonRegionMap_Scene
|
||||
return true
|
||||
end
|
||||
|
||||
# TODO: Why is this PBS file writer here?
|
||||
def pbSaveMapData
|
||||
File.open("PBS/townmap.txt","wb") { |f|
|
||||
f.write(0xEF.chr)
|
||||
@@ -179,10 +180,11 @@ class PokemonRegionMap_Scene
|
||||
next if !map
|
||||
f.write("\#-------------------------------\r\n")
|
||||
f.write(sprintf("[%d]\r\n",i))
|
||||
f.write(sprintf("Name=%s\r\nFilename=%s\r\n",csvQuote(map[0]),csvQuote(map[1])))
|
||||
f.write(sprintf("Name = %s\r\nFilename = %s\r\n",
|
||||
Compiler.csvQuote(map[0]), Compiler.csvQuote(map[1])))
|
||||
for loc in map[2]
|
||||
f.write("Point = ")
|
||||
pbWriteCsvRecord(loc,f,[nil,"uussUUUU"])
|
||||
Compiler.pbWriteCsvRecord(loc,f,[nil,"uussUUUU"])
|
||||
f.write("\r\n")
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1059,7 +1059,7 @@ def pbTrainerInfo(pokemonlist,trfile,rules)
|
||||
yield(nil) if block_given?
|
||||
save_data(trlists,"Data/trainer_lists.dat")
|
||||
yield(nil) if block_given?
|
||||
pbSaveTrainerLists()
|
||||
Compiler.write_trainer_lists
|
||||
yield(nil) if block_given?
|
||||
end
|
||||
|
||||
@@ -1298,8 +1298,7 @@ def pbWriteCup(id,rules)
|
||||
trlists[cmd][2].push(id) if !trlists[cmd][5]
|
||||
save_data(trlists,"Data/trainer_lists.dat")
|
||||
Graphics.update
|
||||
pbSaveTrainerLists
|
||||
Graphics.update
|
||||
Compiler.write_trainer_lists
|
||||
end
|
||||
return
|
||||
# Yes, use new
|
||||
|
||||
@@ -251,11 +251,6 @@ module Mouse
|
||||
@ReleaseCapture = Win32API.new('user32','ReleaseCapture','','i')
|
||||
module_function
|
||||
|
||||
def getMouseGlobalPos
|
||||
pos = [0, 0].pack('ll')
|
||||
return (@GetCursorPos.call(pos)!=0) ? pos.unpack('ll') : [nil,nil]
|
||||
end
|
||||
|
||||
def screen_to_client(x, y)
|
||||
return nil unless x and y
|
||||
screenToClient = Win32API.new('user32','ScreenToClient',%w(l p),'i')
|
||||
@@ -264,12 +259,9 @@ module Mouse
|
||||
return nil
|
||||
end
|
||||
|
||||
def setCapture
|
||||
@SetCapture.call(Win32API.pbFindRgssWindow)
|
||||
end
|
||||
|
||||
def releaseCapture
|
||||
@ReleaseCapture.call
|
||||
def getMouseGlobalPos
|
||||
pos = [0, 0].pack('ll')
|
||||
return (@GetCursorPos.call(pos)!=0) ? pos.unpack('ll') : [nil,nil]
|
||||
end
|
||||
|
||||
# Returns the position of the mouse relative to the game window.
|
||||
@@ -283,6 +275,17 @@ module Mouse
|
||||
return nil
|
||||
end
|
||||
|
||||
# Unused
|
||||
def setCapture
|
||||
@SetCapture.call(Win32API.pbFindRgssWindow)
|
||||
end
|
||||
|
||||
# Unused
|
||||
def releaseCapture
|
||||
@ReleaseCapture.call
|
||||
end
|
||||
|
||||
# Unused
|
||||
def del
|
||||
return if @oldcursor==nil
|
||||
@SetClassLong.call(Win32API.pbFindRgssWindow,-12,@oldcursor)
|
||||
|
||||
@@ -63,16 +63,6 @@ def pbSetUpSystem
|
||||
pbSetResizeFactor([$PokemonSystem.screensize, 4].min)
|
||||
end
|
||||
# Load constants
|
||||
begin
|
||||
consts = pbSafeLoad("Data/Constants.rxdata")
|
||||
consts = [] if !consts
|
||||
rescue
|
||||
consts = []
|
||||
end
|
||||
for script in consts
|
||||
next if !script
|
||||
eval(Zlib::Inflate.inflate(script[2]),nil,script[1])
|
||||
end
|
||||
GameData.load_all
|
||||
if LANGUAGES.length>=2
|
||||
pokemonSystem.language = pbChooseLanguage if !havedata
|
||||
|
||||
@@ -235,6 +235,22 @@ def getID(mod,constant)
|
||||
return constant
|
||||
end
|
||||
|
||||
def getConstantName(mod,value)
|
||||
mod = Object.const_get(mod) if mod.is_a?(Symbol)
|
||||
for c in mod.constants
|
||||
return c if mod.const_get(c.to_sym)==value
|
||||
end
|
||||
raise _INTL("Value {1} not defined by a constant in {2}",value,mod.name)
|
||||
end
|
||||
|
||||
def getConstantNameOrValue(mod,value)
|
||||
mod = Object.const_get(mod) if mod.is_a?(Symbol)
|
||||
for c in mod.constants
|
||||
return c if mod.const_get(c.to_sym)==value
|
||||
end
|
||||
return value.inspect
|
||||
end
|
||||
|
||||
|
||||
|
||||
#===============================================================================
|
||||
|
||||
@@ -896,7 +896,7 @@ DebugMenuCommands.register("setencounters", {
|
||||
end
|
||||
save_data(encdata, "Data/encounters.dat")
|
||||
$PokemonTemp.encountersData = nil
|
||||
pbSaveEncounterData # Rewrite PBS file encounters.txt
|
||||
Compiler.write_encounters # Rewrite PBS file encounters.txt
|
||||
}
|
||||
})
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,945 @@
|
||||
module ShadowText
|
||||
def shadowtext(bitmap,x,y,w,h,t,disabled=false,align=0)
|
||||
width=bitmap.text_size(t).width
|
||||
if align==2
|
||||
x+=(w-width)
|
||||
elsif align==1
|
||||
x+=(w/2)-(width/2)
|
||||
end
|
||||
pbDrawShadowText(bitmap,x,y+6,w,h,t,
|
||||
disabled ? Color.new(26*8,26*8,25*8) : Color.new(12*8,12*8,12*8),
|
||||
Color.new(26*8,26*8,25*8))
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
class UIControl
|
||||
include ShadowText
|
||||
attr_accessor :bitmap
|
||||
attr_accessor :label
|
||||
attr_accessor :x
|
||||
attr_accessor :y
|
||||
attr_accessor :width
|
||||
attr_accessor :height
|
||||
attr_accessor :changed
|
||||
attr_accessor :parent
|
||||
attr_accessor :disabled
|
||||
|
||||
def text
|
||||
return self.label
|
||||
end
|
||||
|
||||
def text=(value)
|
||||
self.label=value
|
||||
end
|
||||
|
||||
def initialize(label)
|
||||
@label=label
|
||||
@x=0
|
||||
@y=0
|
||||
@width=0
|
||||
@height=0
|
||||
@changed=false
|
||||
@disabled=false
|
||||
@invalid=true
|
||||
end
|
||||
|
||||
def toAbsoluteRect(rc)
|
||||
return Rect.new(
|
||||
rc.x+self.parentX,
|
||||
rc.y+self.parentY,
|
||||
rc.width,rc.height)
|
||||
end
|
||||
|
||||
def parentX
|
||||
return 0 if !self.parent
|
||||
return self.parent.x+self.parent.leftEdge if self.parent.is_a?(SpriteWindow)
|
||||
return self.parent.x+16 if self.parent.is_a?(Window)
|
||||
return self.parent.x
|
||||
end
|
||||
|
||||
def parentY
|
||||
return 0 if !self.parent
|
||||
return self.parent.y+self.parent.topEdge if self.parent.is_a?(SpriteWindow)
|
||||
return self.parent.y+16 if self.parent.is_a?(Window)
|
||||
return self.parent.y
|
||||
end
|
||||
|
||||
def invalid?
|
||||
return @invalid
|
||||
end
|
||||
|
||||
def invalidate # Marks that the control must be redrawn to reflect current logic
|
||||
@invalid=true
|
||||
end
|
||||
|
||||
def update # Updates the logic on the control, invalidating it if necessary
|
||||
end
|
||||
|
||||
def refresh # Redraws the control
|
||||
end
|
||||
|
||||
def validate # Makes the control no longer invalid
|
||||
@invalid=false
|
||||
end
|
||||
|
||||
def repaint # Redraws the control only if it is invalid
|
||||
if self.invalid?
|
||||
self.refresh
|
||||
self.validate
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
class Label < UIControl
|
||||
def text=(value)
|
||||
self.label=value
|
||||
refresh
|
||||
end
|
||||
|
||||
def refresh
|
||||
bitmap=self.bitmap
|
||||
bitmap.fill_rect(self.x,self.y,self.width,self.height,Color.new(0,0,0,0))
|
||||
size=bitmap.text_size(self.label).width
|
||||
shadowtext(bitmap,self.x+4,self.y,size,self.height,self.label,@disabled)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
class Button < UIControl
|
||||
attr_accessor :label
|
||||
|
||||
def initialize(label)
|
||||
super
|
||||
@captured=false
|
||||
@label=label
|
||||
end
|
||||
|
||||
def update
|
||||
mousepos=Mouse::getMousePos
|
||||
self.changed=false
|
||||
return if !mousepos
|
||||
rect=Rect.new(self.x+1,self.y+1,self.width-2,self.height-2)
|
||||
rect=toAbsoluteRect(rect)
|
||||
if Input.triggerex?(Input::LeftMouseKey) &&
|
||||
rect.contains(mousepos[0],mousepos[1]) && !@captured
|
||||
@captured=true
|
||||
self.invalidate
|
||||
end
|
||||
if Input.releaseex?(Input::LeftMouseKey) && @captured
|
||||
self.changed=true if rect.contains(mousepos[0],mousepos[1])
|
||||
@captured=false
|
||||
self.invalidate
|
||||
end
|
||||
end
|
||||
|
||||
def refresh
|
||||
bitmap=self.bitmap
|
||||
x=self.x
|
||||
y=self.y
|
||||
width=self.width
|
||||
height=self.height
|
||||
color=Color.new(120,120,120)
|
||||
bitmap.fill_rect(x+1,y+1,width-2,height-2,color)
|
||||
ret=Rect.new(x+1,y+1,width-2,height-2)
|
||||
if !@captured
|
||||
bitmap.fill_rect(x+2,y+2,width-4,height-4,Color.new(0,0,0,0))
|
||||
else
|
||||
bitmap.fill_rect(x+2,y+2,width-4,height-4,Color.new(120,120,120,80))
|
||||
end
|
||||
size=bitmap.text_size(self.label).width
|
||||
shadowtext(bitmap,x+4,y,size,height,self.label,@disabled)
|
||||
return ret
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
class Checkbox < Button
|
||||
attr_reader :checked
|
||||
|
||||
def curvalue
|
||||
return self.checked
|
||||
end
|
||||
|
||||
def curvalue=(value)
|
||||
self.checked=value
|
||||
end
|
||||
|
||||
def checked=(value)
|
||||
@checked=value
|
||||
invalidate
|
||||
end
|
||||
|
||||
def initialize(label)
|
||||
super
|
||||
@checked=false
|
||||
end
|
||||
|
||||
def update
|
||||
super
|
||||
if self.changed
|
||||
@checked=!@checked
|
||||
self.invalidate
|
||||
end
|
||||
end
|
||||
|
||||
def refresh
|
||||
bitmap=self.bitmap
|
||||
x=self.x
|
||||
y=self.y
|
||||
width=[self.width,32].min
|
||||
height=[self.height,32].min
|
||||
color=Color.new(120,120,120)
|
||||
bitmap.fill_rect(x+2,y+2,self.width-4,self.height-4,Color.new(0,0,0,0))
|
||||
bitmap.fill_rect(x+1,y+1,width-2,height-2,color)
|
||||
ret=Rect.new(x+1,y+1,width-2,height-2)
|
||||
if !@captured
|
||||
bitmap.fill_rect(x+2,y+2,width-4,height-4,Color.new(0,0,0,0))
|
||||
else
|
||||
bitmap.fill_rect(x+2,y+2,width-4,height-4,Color.new(120,120,120,80))
|
||||
end
|
||||
if self.checked
|
||||
shadowtext(bitmap,x,y,32,32,"X",@disabled,1)
|
||||
end
|
||||
size=bitmap.text_size(self.label).width
|
||||
shadowtext(bitmap,x+36,y,size,height,self.label,@disabled)
|
||||
return ret
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
class TextField < UIControl
|
||||
attr_accessor :label
|
||||
attr_reader :text
|
||||
|
||||
def text=(value)
|
||||
@text=value
|
||||
self.invalidate
|
||||
end
|
||||
|
||||
def initialize(label,text)
|
||||
super(label)
|
||||
@frame=0
|
||||
@label=label
|
||||
@text=text
|
||||
@cursor=text.scan(/./m).length
|
||||
end
|
||||
|
||||
def insert(ch)
|
||||
chars=self.text.scan(/./m)
|
||||
chars.insert(@cursor,ch)
|
||||
@text=""
|
||||
for ch in chars
|
||||
@text+=ch
|
||||
end
|
||||
@cursor+=1
|
||||
@frame=0
|
||||
self.changed=true
|
||||
self.invalidate
|
||||
end
|
||||
|
||||
def delete
|
||||
chars=self.text.scan(/./m)
|
||||
chars.delete_at(@cursor-1)
|
||||
@text=""
|
||||
for ch in chars
|
||||
@text+=ch
|
||||
end
|
||||
@cursor-=1
|
||||
@frame=0
|
||||
self.changed=true
|
||||
self.invalidate
|
||||
end
|
||||
|
||||
def update
|
||||
@frame+=1
|
||||
@frame%=20
|
||||
self.changed=false
|
||||
self.invalidate if ((@frame%10)==0)
|
||||
# Moving cursor
|
||||
if Input.repeat?(Input::LEFT)
|
||||
if @cursor > 0
|
||||
@cursor-=1
|
||||
@frame=0
|
||||
self.invalidate
|
||||
end
|
||||
return
|
||||
end
|
||||
if Input.repeat?(Input::RIGHT)
|
||||
if @cursor < self.text.scan(/./m).length
|
||||
@cursor+=1
|
||||
@frame=0
|
||||
self.invalidate
|
||||
end
|
||||
return
|
||||
end
|
||||
# Backspace
|
||||
if Input.repeat?(Input::BACKSPACE) || Input.repeat?(Input::DELETE)
|
||||
self.delete if @cursor > 0
|
||||
return
|
||||
end
|
||||
# Letter keys
|
||||
for i in 65..90
|
||||
if Input.repeatex?(i)
|
||||
shift=(Input.press?(Input::SHIFT)) ? 0x41 : 0x61
|
||||
insert((shift+i-65).chr)
|
||||
return
|
||||
end
|
||||
end
|
||||
# Number keys
|
||||
shifted=")!@\#$%^&*("
|
||||
unshifted="0123456789"
|
||||
for i in 48..57
|
||||
if Input.repeatex?(i)
|
||||
insert((Input.press?(Input::SHIFT)) ? shifted[i-48].chr : unshifted[i-48].chr)
|
||||
return
|
||||
end
|
||||
end
|
||||
keys=[
|
||||
[32," "," "],
|
||||
[106,"*","*"],
|
||||
[107,"+","+"],
|
||||
[109,"-","-"],
|
||||
[111,"/","/"],
|
||||
[186,";",":"],
|
||||
[187,"=","+"],
|
||||
[188,",","<"],
|
||||
[189,"-","_"],
|
||||
[190,".",">"],
|
||||
[191,"/","?"],
|
||||
[219,"[","{"],
|
||||
[220,"\\","|"],
|
||||
[221,"]","}"],
|
||||
[222,"\"","'"]
|
||||
]
|
||||
for i in keys
|
||||
if Input.repeatex?(i[0])
|
||||
insert((Input.press?(Input::SHIFT)) ? i[2] : i[1])
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def refresh
|
||||
bitmap=self.bitmap
|
||||
x=self.x
|
||||
y=self.y
|
||||
width=self.width
|
||||
height=self.height
|
||||
color=Color.new(120,120,120)
|
||||
bitmap.font.color=color
|
||||
bitmap.fill_rect(x,y,width,height,Color.new(0,0,0,0))
|
||||
size=bitmap.text_size(self.label).width
|
||||
shadowtext(bitmap,x,y,size,height,self.label)
|
||||
x+=size
|
||||
width-=size
|
||||
bitmap.fill_rect(x+1,y+1,width-2,height-2,color)
|
||||
ret=Rect.new(x+1,y+1,width-2,height-2)
|
||||
if !@captured
|
||||
bitmap.fill_rect(x+2,y+2,width-4,height-4,Color.new(0,0,0,0))
|
||||
else
|
||||
bitmap.fill_rect(x+2,y+2,width-4,height-4,Color.new(120,120,120,80))
|
||||
end
|
||||
x+=4
|
||||
textscan=self.text.scan(/./m)
|
||||
scanlength=textscan.length
|
||||
@cursor=scanlength if @cursor>scanlength
|
||||
@cursor=0 if @cursor<0
|
||||
startpos=@cursor
|
||||
fromcursor=0
|
||||
while (startpos>0)
|
||||
c=textscan[startpos-1]
|
||||
fromcursor+=bitmap.text_size(c).width
|
||||
break if fromcursor>width-4
|
||||
startpos-=1
|
||||
end
|
||||
for i in startpos...scanlength
|
||||
c=textscan[i]
|
||||
textwidth=bitmap.text_size(c).width
|
||||
next if c=="\n"
|
||||
# Draw text
|
||||
shadowtext(bitmap,x,y, textwidth+4, 32, c)
|
||||
# Draw cursor if necessary
|
||||
if ((@frame/10)&1) == 0 && i==@cursor
|
||||
bitmap.fill_rect(x,y+4,2,24,Color.new(120,120,120))
|
||||
end
|
||||
# Add x to drawn text width
|
||||
x += textwidth
|
||||
end
|
||||
if ((@frame/10)&1) == 0 && textscan.length==@cursor
|
||||
bitmap.fill_rect(x,y+4,2,24,Color.new(120,120,120))
|
||||
end
|
||||
return ret
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
class Slider < UIControl
|
||||
attr_reader :minvalue
|
||||
attr_reader :maxvalue
|
||||
attr_reader :curvalue
|
||||
attr_accessor :label
|
||||
|
||||
def curvalue=(value)
|
||||
@curvalue=value
|
||||
@curvalue=self.minvalue if self.minvalue && @curvalue<self.minvalue
|
||||
@curvalue=self.maxvalue if self.maxvalue && @curvalue>self.maxvalue
|
||||
self.invalidate
|
||||
end
|
||||
|
||||
def minvalue=(value)
|
||||
@minvalue=value
|
||||
@curvalue=self.minvalue if self.minvalue && @curvalue<self.minvalue
|
||||
@curvalue=self.maxvalue if self.maxvalue && @curvalue>self.maxvalue
|
||||
self.invalidate
|
||||
end
|
||||
|
||||
def maxvalue=(value)
|
||||
@maxvalue=value
|
||||
@curvalue=self.minvalue if self.minvalue && @curvalue<self.minvalue
|
||||
@curvalue=self.maxvalue if self.maxvalue && @curvalue>self.maxvalue
|
||||
self.invalidate
|
||||
end
|
||||
|
||||
def initialize(label,minvalue,maxvalue,curval)
|
||||
super(label)
|
||||
@minvalue=minvalue
|
||||
@maxvalue=maxvalue
|
||||
@curvalue=curval
|
||||
@label=label
|
||||
@leftarrow=Rect.new(0,0,0,0)
|
||||
@rightarrow=Rect.new(0,0,0,0)
|
||||
self.minvalue=minvalue
|
||||
self.maxvalue=maxvalue
|
||||
self.curvalue=curval
|
||||
end
|
||||
|
||||
def update
|
||||
mousepos=Mouse::getMousePos
|
||||
self.changed=false
|
||||
if self.minvalue<self.maxvalue && self.curvalue<self.minvalue
|
||||
self.curvalue=self.minvalue
|
||||
end
|
||||
return false if self.disabled
|
||||
return false if !Input.repeatex?(Input::LeftMouseKey)
|
||||
return false if !mousepos
|
||||
left=toAbsoluteRect(@leftarrow)
|
||||
right=toAbsoluteRect(@rightarrow)
|
||||
oldvalue=self.curvalue
|
||||
# Left arrow
|
||||
if left.contains(mousepos[0],mousepos[1])
|
||||
if Input.repeatcount(Input::LeftMouseKey)>100
|
||||
self.curvalue-=10
|
||||
self.curvalue=self.curvalue.floor
|
||||
elsif Input.repeatcount(Input::LeftMouseKey)>50
|
||||
self.curvalue-=5
|
||||
self.curvalue=self.curvalue.floor
|
||||
else
|
||||
self.curvalue-=1
|
||||
self.curvalue=self.curvalue.floor
|
||||
end
|
||||
self.changed=(self.curvalue!=oldvalue)
|
||||
self.invalidate
|
||||
end
|
||||
#Right arrow
|
||||
if right.contains(mousepos[0],mousepos[1])
|
||||
if Input.repeatcount(Input::LeftMouseKey)>100
|
||||
self.curvalue+=10
|
||||
self.curvalue=self.curvalue.floor
|
||||
elsif Input.repeatcount(Input::LeftMouseKey)>50
|
||||
self.curvalue+=5
|
||||
self.curvalue=self.curvalue.floor
|
||||
else
|
||||
self.curvalue+=1
|
||||
self.curvalue=self.curvalue.floor
|
||||
end
|
||||
self.changed=(self.curvalue!=oldvalue)
|
||||
self.invalidate
|
||||
end
|
||||
end
|
||||
|
||||
def refresh
|
||||
bitmap=self.bitmap
|
||||
x=self.x
|
||||
y=self.y
|
||||
width=self.width
|
||||
height=self.height
|
||||
color=Color.new(120,120,120)
|
||||
bitmap.fill_rect(x,y,width,height,Color.new(0,0,0,0))
|
||||
size=bitmap.text_size(self.label).width
|
||||
leftarrows=bitmap.text_size(_INTL(" << "))
|
||||
numbers=bitmap.text_size(" XXXX ").width
|
||||
rightarrows=bitmap.text_size(_INTL(" >> "))
|
||||
bitmap.font.color=color
|
||||
shadowtext(bitmap,x,y,size,height,self.label)
|
||||
x+=size
|
||||
shadowtext(bitmap,x,y,leftarrows.width,height,_INTL(" << "),
|
||||
self.disabled || self.curvalue==self.minvalue)
|
||||
@leftarrow=Rect.new(x,y,leftarrows.width,height)
|
||||
x+=leftarrows.width
|
||||
if !self.disabled
|
||||
bitmap.font.color=color
|
||||
shadowtext(bitmap,x,y,numbers,height," #{self.curvalue} ",false,1)
|
||||
end
|
||||
x+=numbers
|
||||
shadowtext(bitmap,x,y,rightarrows.width,height,_INTL(" >> "),
|
||||
self.disabled || self.curvalue==self.maxvalue)
|
||||
@rightarrow=Rect.new(x,y,rightarrows.width,height)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
class OptionalSlider < Slider
|
||||
def initialize(label,minvalue,maxvalue,curvalue)
|
||||
@slider=Slider.new(label,minvalue,maxvalue,curvalue)
|
||||
@checkbox=Checkbox.new("")
|
||||
end
|
||||
|
||||
def curvalue
|
||||
return @checkbox.checked ? @slider.curvalue : nil
|
||||
end
|
||||
|
||||
def curvalue=(value)
|
||||
slider.curvalue=value
|
||||
end
|
||||
|
||||
def checked
|
||||
return @checkbox.checked
|
||||
end
|
||||
|
||||
def checked=(value)
|
||||
@checkbox.checked=value
|
||||
end
|
||||
|
||||
def invalid?
|
||||
return @slider.invalid? || @checkbox.invalid?
|
||||
end
|
||||
|
||||
def invalidate
|
||||
@slider.invalidate
|
||||
@checkbox.invalidate
|
||||
end
|
||||
|
||||
def validate?
|
||||
@slider.validate
|
||||
@checkbox.validate
|
||||
end
|
||||
|
||||
def changed
|
||||
return @slider.changed || @checkbox.changed
|
||||
end
|
||||
|
||||
def minvalue
|
||||
return @slider.minvalue
|
||||
end
|
||||
|
||||
def minvalue=(value)
|
||||
slider.minvalue=value
|
||||
end
|
||||
|
||||
def maxvalue
|
||||
return @slider.maxvalue
|
||||
end
|
||||
|
||||
def maxvalue=(value)
|
||||
slider.maxvalue=value
|
||||
end
|
||||
|
||||
def update
|
||||
updatedefs
|
||||
@slider.update
|
||||
@checkbox.update
|
||||
end
|
||||
|
||||
def refresh
|
||||
updatedefs
|
||||
@slider.refresh
|
||||
@checkbox.refresh
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def updatedefs
|
||||
checkboxwidth=32
|
||||
@slider.bitmap=self.bitmap
|
||||
@slider.parent=self.parent
|
||||
@checkbox.x=self.x
|
||||
@checkbox.y=self.y
|
||||
@checkbox.width=checkboxwidth
|
||||
@checkbox.height=self.height
|
||||
@checkbox.bitmap=self.bitmap
|
||||
@checkbox.parent=self.parent
|
||||
@slider.x=self.x+checkboxwidth+4
|
||||
@slider.y=self.y
|
||||
@slider.width=self.width-checkboxwidth
|
||||
@slider.height=self.height
|
||||
@slider.disabled=!@checkbox.checked
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
class ArrayCountSlider < Slider
|
||||
def maxvalue
|
||||
return @array.length-1
|
||||
end
|
||||
|
||||
def initialize(array,label)
|
||||
@array=array
|
||||
super(label,0,canvas.animation.length-1,0)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
class FrameCountSlider < Slider
|
||||
def maxvalue
|
||||
return @canvas.animation.length
|
||||
end
|
||||
|
||||
def initialize(canvas)
|
||||
@canvas=canvas
|
||||
super(_INTL("Frame:"),1,canvas.animation.length,0)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
class FrameCountButton < Button
|
||||
def label
|
||||
return _INTL("Total Frames: {1}",@canvas.animation.length)
|
||||
end
|
||||
|
||||
def initialize(canvas)
|
||||
@canvas=canvas
|
||||
super(self.label)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
class TextSlider < UIControl
|
||||
attr_reader :minvalue
|
||||
attr_reader :maxvalue
|
||||
attr_reader :curvalue
|
||||
attr_accessor :label
|
||||
attr_accessor :options
|
||||
attr_accessor :maxoptionwidth
|
||||
|
||||
def curvalue=(value)
|
||||
@curvalue=value
|
||||
@curvalue=self.minvalue if self.minvalue && @curvalue<self.minvalue
|
||||
@curvalue=self.maxvalue if self.maxvalue && @curvalue>self.maxvalue
|
||||
self.invalidate
|
||||
end
|
||||
|
||||
def minvalue=(value)
|
||||
@minvalue=value
|
||||
@curvalue=self.minvalue if self.minvalue && @curvalue<self.minvalue
|
||||
@curvalue=self.maxvalue if self.maxvalue && @curvalue>self.maxvalue
|
||||
self.invalidate
|
||||
end
|
||||
|
||||
def maxvalue=(value)
|
||||
@maxvalue=value
|
||||
@curvalue=self.minvalue if self.minvalue && @curvalue<self.minvalue
|
||||
@curvalue=self.maxvalue if self.maxvalue && @curvalue>self.maxvalue
|
||||
self.invalidate
|
||||
end
|
||||
|
||||
def initialize(label,options,curval)
|
||||
super(label)
|
||||
@label=label
|
||||
@options=options
|
||||
@minvalue=0
|
||||
@maxvalue=options.length-1
|
||||
@curvalue=curval
|
||||
@leftarrow=Rect.new(0,0,0,0)
|
||||
@rightarrow=Rect.new(0,0,0,0)
|
||||
self.minvalue=@minvalue
|
||||
self.maxvalue=@maxvalue
|
||||
self.curvalue=@curvalue
|
||||
end
|
||||
|
||||
def update
|
||||
mousepos=Mouse::getMousePos
|
||||
self.changed=false
|
||||
if self.minvalue<self.maxvalue && self.curvalue<self.minvalue
|
||||
self.curvalue=self.minvalue
|
||||
end
|
||||
return false if self.disabled
|
||||
return false if !Input.repeatex?(Input::LeftMouseKey)
|
||||
return false if !mousepos
|
||||
left=toAbsoluteRect(@leftarrow)
|
||||
right=toAbsoluteRect(@rightarrow)
|
||||
oldvalue=self.curvalue
|
||||
# Left arrow
|
||||
if left.contains(mousepos[0],mousepos[1])
|
||||
if Input.repeatcount(Input::LeftMouseKey)>100
|
||||
self.curvalue-=10
|
||||
elsif Input.repeatcount(Input::LeftMouseKey)>50
|
||||
self.curvalue-=5
|
||||
else
|
||||
self.curvalue-=1
|
||||
end
|
||||
self.changed=(self.curvalue!=oldvalue)
|
||||
self.invalidate
|
||||
end
|
||||
# Right arrow
|
||||
if right.contains(mousepos[0],mousepos[1])
|
||||
if Input.repeatcount(Input::LeftMouseKey)>100
|
||||
self.curvalue+=10
|
||||
elsif Input.repeatcount(Input::LeftMouseKey)>50
|
||||
self.curvalue+=5
|
||||
else
|
||||
self.curvalue+=1
|
||||
end
|
||||
self.changed=(self.curvalue!=oldvalue)
|
||||
self.invalidate
|
||||
end
|
||||
end
|
||||
|
||||
def refresh
|
||||
bitmap=self.bitmap
|
||||
if @maxoptionwidth==nil
|
||||
for i in 0...@options.length
|
||||
w=self.bitmap.text_size(" "+@options[i]+" ").width
|
||||
@maxoptionwidth=w if !@maxoptionwidth || @maxoptionwidth<w
|
||||
end
|
||||
end
|
||||
x=self.x
|
||||
y=self.y
|
||||
width=self.width
|
||||
height=self.height
|
||||
color=Color.new(120,120,120)
|
||||
bitmap.fill_rect(x,y,width,height,Color.new(0,0,0,0))
|
||||
size=bitmap.text_size(self.label).width
|
||||
leftarrows=bitmap.text_size(_INTL(" << "))
|
||||
rightarrows=bitmap.text_size(_INTL(" >> "))
|
||||
bitmap.font.color=color
|
||||
shadowtext(bitmap,x,y,size,height,self.label)
|
||||
x+=size
|
||||
shadowtext(bitmap,x,y,leftarrows.width,height,_INTL(" << "),
|
||||
self.disabled || self.curvalue==self.minvalue)
|
||||
@leftarrow=Rect.new(x,y,leftarrows.width,height)
|
||||
x+=leftarrows.width
|
||||
if !self.disabled
|
||||
bitmap.font.color=color
|
||||
shadowtext(bitmap,x,y,@maxoptionwidth,height," #{@options[self.curvalue]} ",false,1)
|
||||
end
|
||||
x+=@maxoptionwidth
|
||||
shadowtext(bitmap,x,y,rightarrows.width,height,_INTL(" >> "),
|
||||
self.disabled || self.curvalue==self.maxvalue)
|
||||
@rightarrow=Rect.new(x,y,rightarrows.width,height)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
class OptionalTextSlider < TextSlider
|
||||
def initialize(label,options,curval)
|
||||
@slider=TextSlider.new(label,options,curval)
|
||||
@checkbox=Checkbox.new("")
|
||||
end
|
||||
|
||||
def curvalue
|
||||
return @checkbox.checked ? @slider.curvalue : nil
|
||||
end
|
||||
|
||||
def curvalue=(value)
|
||||
slider.curvalue=value
|
||||
end
|
||||
|
||||
def checked
|
||||
return @checkbox.checked
|
||||
end
|
||||
|
||||
def checked=(value)
|
||||
@checkbox.checked=value
|
||||
end
|
||||
|
||||
def invalid?
|
||||
return @slider.invalid? || @checkbox.invalid?
|
||||
end
|
||||
|
||||
def invalidate
|
||||
@slider.invalidate
|
||||
@checkbox.invalidate
|
||||
end
|
||||
|
||||
def validate?
|
||||
@slider.validate
|
||||
@checkbox.validate
|
||||
end
|
||||
|
||||
def changed
|
||||
return @slider.changed || @checkbox.changed
|
||||
end
|
||||
|
||||
def minvalue
|
||||
return @slider.minvalue
|
||||
end
|
||||
|
||||
def minvalue=(value)
|
||||
slider.minvalue=value
|
||||
end
|
||||
|
||||
def maxvalue
|
||||
return @slider.maxvalue
|
||||
end
|
||||
|
||||
def maxvalue=(value)
|
||||
slider.maxvalue=value
|
||||
end
|
||||
|
||||
def update
|
||||
updatedefs
|
||||
@slider.update
|
||||
@checkbox.update
|
||||
end
|
||||
|
||||
def refresh
|
||||
updatedefs
|
||||
@slider.refresh
|
||||
@checkbox.refresh
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def updatedefs
|
||||
checkboxwidth=32
|
||||
@slider.bitmap=self.bitmap
|
||||
@slider.parent=self.parent
|
||||
@checkbox.x=self.x
|
||||
@checkbox.y=self.y
|
||||
@checkbox.width=checkboxwidth
|
||||
@checkbox.height=self.height
|
||||
@checkbox.bitmap=self.bitmap
|
||||
@checkbox.parent=self.parent
|
||||
@slider.x=self.x+checkboxwidth+4
|
||||
@slider.y=self.y
|
||||
@slider.width=self.width-checkboxwidth
|
||||
@slider.height=self.height
|
||||
@slider.disabled=!@checkbox.checked
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
class ControlWindow < SpriteWindow_Base
|
||||
attr_reader :controls
|
||||
|
||||
def initialize(x,y,width,height)
|
||||
super(x,y,width,height)
|
||||
self.contents=Bitmap.new(width-32,height-32)
|
||||
pbSetNarrowFont(self.contents)
|
||||
@controls=[]
|
||||
end
|
||||
|
||||
def dispose
|
||||
self.contents.dispose
|
||||
super
|
||||
end
|
||||
|
||||
def refresh
|
||||
for i in 0...@controls.length
|
||||
@controls[i].refresh
|
||||
end
|
||||
end
|
||||
|
||||
def repaint
|
||||
for i in 0...@controls.length
|
||||
@controls[i].repaint
|
||||
end
|
||||
end
|
||||
|
||||
def invalidate
|
||||
for i in 0...@controls.length
|
||||
@controls[i].invalidate
|
||||
end
|
||||
end
|
||||
|
||||
def hittest?(i)
|
||||
mousepos=Mouse::getMousePos
|
||||
return false if !mousepos
|
||||
return false if i<0 || i>=@controls.length
|
||||
rc=Rect.new(
|
||||
@controls[i].parentX,
|
||||
@controls[i].parentY,
|
||||
@controls[i].width,
|
||||
@controls[i].height
|
||||
)
|
||||
return rc.contains(mousepos[0],mousepos[1])
|
||||
end
|
||||
|
||||
def addControl(control)
|
||||
i=@controls.length
|
||||
@controls[i]=control
|
||||
@controls[i].x=0
|
||||
@controls[i].y=i*32
|
||||
@controls[i].width=self.contents.width
|
||||
@controls[i].height=32
|
||||
@controls[i].parent=self
|
||||
@controls[i].bitmap=self.contents
|
||||
@controls[i].invalidate
|
||||
refresh
|
||||
return i
|
||||
end
|
||||
|
||||
def addLabel(label)
|
||||
return addControl(Label.new(label))
|
||||
end
|
||||
|
||||
def addButton(label)
|
||||
return addControl(Button.new(label))
|
||||
end
|
||||
|
||||
def addSlider(label,minvalue,maxvalue,curvalue)
|
||||
return addControl(Slider.new(label,minvalue,maxvalue,curvalue))
|
||||
end
|
||||
|
||||
def addOptionalSlider(label,minvalue,maxvalue,curvalue)
|
||||
return addControl(OptionalSlider.new(label,minvalue,maxvalue,curvalue))
|
||||
end
|
||||
|
||||
def addTextSlider(label,options,curvalue)
|
||||
return addControl(TextSlider.new(label,options,curvalue))
|
||||
end
|
||||
|
||||
def addOptionalTextSlider(label,options,curvalue)
|
||||
return addControl(OptionalTextSlider.new(label,options,curvalue))
|
||||
end
|
||||
|
||||
def addCheckbox(label)
|
||||
return addControl(Checkbox.new(label))
|
||||
end
|
||||
|
||||
def addSpace
|
||||
return addControl(UIControl.new(""))
|
||||
end
|
||||
|
||||
def update
|
||||
super
|
||||
for i in 0...@controls.length
|
||||
@controls[i].update
|
||||
end
|
||||
repaint
|
||||
end
|
||||
|
||||
def changed?(i)
|
||||
return false if i<0
|
||||
return @controls[i].changed
|
||||
end
|
||||
|
||||
def value(i)
|
||||
return false if i<0
|
||||
return @controls[i].curvalue
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,444 @@
|
||||
################################################################################
|
||||
# Paths and interpolation
|
||||
################################################################################
|
||||
class ControlPointSprite < SpriteWrapper
|
||||
attr_accessor :dragging
|
||||
|
||||
def initialize(red,viewport=nil)
|
||||
super(viewport)
|
||||
self.bitmap=Bitmap.new(6,6)
|
||||
self.bitmap.fill_rect(0,0,6,1,Color.new(0,0,0))
|
||||
self.bitmap.fill_rect(0,0,1,6,Color.new(0,0,0))
|
||||
self.bitmap.fill_rect(0,5,6,1,Color.new(0,0,0))
|
||||
self.bitmap.fill_rect(5,0,1,6,Color.new(0,0,0))
|
||||
color=(red) ? Color.new(255,0,0) : Color.new(0,0,0)
|
||||
self.bitmap.fill_rect(2,2,2,2,color)
|
||||
self.x=-6
|
||||
self.y=-6
|
||||
self.visible=false
|
||||
@dragging=false
|
||||
end
|
||||
|
||||
def mouseover
|
||||
if Input.repeatcount(Input::LeftMouseKey)==0 || !@dragging
|
||||
@dragging=false
|
||||
return
|
||||
end
|
||||
mouse=Mouse::getMousePos(true)
|
||||
return if !mouse
|
||||
self.x=[[mouse[0],0].max,512].min
|
||||
self.y=[[mouse[1],0].max,384].min
|
||||
end
|
||||
|
||||
def hittest?
|
||||
return true if !self.visible
|
||||
mouse=Mouse::getMousePos(true)
|
||||
return false if !mouse
|
||||
return mouse[0]>=self.x && mouse[0]<self.x+6 &&
|
||||
mouse[1]>=self.y && mouse[1]<self.y+6
|
||||
end
|
||||
|
||||
def inspect
|
||||
return "[#{self.x},#{self.y}]"
|
||||
end
|
||||
|
||||
def dispose
|
||||
self.bitmap.dispose
|
||||
super
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
class PointSprite < SpriteWrapper
|
||||
def initialize(x,y,viewport=nil)
|
||||
super(viewport)
|
||||
self.bitmap=Bitmap.new(2,2)
|
||||
self.bitmap.fill_rect(0,0,2,2,Color.new(0,0,0))
|
||||
self.x=x
|
||||
self.y=y
|
||||
end
|
||||
|
||||
def dispose
|
||||
self.bitmap.dispose
|
||||
super
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
class PointPath
|
||||
include Enumerable
|
||||
|
||||
def initialize
|
||||
@points=[]
|
||||
@distances=[]
|
||||
@totaldist=0
|
||||
end
|
||||
|
||||
def [](x)
|
||||
return @points[x].clone
|
||||
end
|
||||
|
||||
def each
|
||||
@points.each { |o| yield o.clone }
|
||||
end
|
||||
|
||||
def size
|
||||
return @points.size
|
||||
end
|
||||
|
||||
def length
|
||||
return @points.length
|
||||
end
|
||||
|
||||
def totalDistance
|
||||
return @totaldist
|
||||
end
|
||||
|
||||
def inspect
|
||||
p=[]
|
||||
for point in @points
|
||||
p.push([point[0].to_i,point[1].to_i])
|
||||
end
|
||||
return p.inspect
|
||||
end
|
||||
|
||||
def isEndPoint?(x,y)
|
||||
return false if @points.length==0
|
||||
index=@points.length-1
|
||||
return @points[index][0]==x &&
|
||||
@points[index][1]==y
|
||||
end
|
||||
|
||||
def addPoint(x,y)
|
||||
@points.push([x,y])
|
||||
if @points.length>1
|
||||
len=@points.length
|
||||
dx=@points[len-2][0]-@points[len-1][0]
|
||||
dy=@points[len-2][1]-@points[len-1][1]
|
||||
dist=Math.sqrt(dx*dx+dy*dy)
|
||||
@distances.push(dist)
|
||||
@totaldist+=dist
|
||||
end
|
||||
end
|
||||
|
||||
def clear
|
||||
@points.clear
|
||||
@distances.clear
|
||||
@totaldist=0
|
||||
end
|
||||
|
||||
def smoothPointPath(frames,roundValues=false)
|
||||
if frames<0
|
||||
raise ArgumentError.new("frames out of range: #{frames}")
|
||||
end
|
||||
ret=PointPath.new
|
||||
if @points.length==0
|
||||
return ret
|
||||
end
|
||||
step=1.0/frames
|
||||
t=0.0
|
||||
(frames+2).times do
|
||||
point=pointOnPath(t)
|
||||
if roundValues
|
||||
ret.addPoint(point[0].round,point[1].round)
|
||||
else
|
||||
ret.addPoint(point[0],point[1])
|
||||
end
|
||||
t+=step
|
||||
t=[1.0,t].min
|
||||
end
|
||||
return ret
|
||||
end
|
||||
|
||||
def pointOnPath(t)
|
||||
if t<0 || t>1
|
||||
raise ArgumentError.new("t out of range for pointOnPath: #{t}")
|
||||
end
|
||||
return nil if @points.length==0
|
||||
ret=@points[@points.length-1].clone
|
||||
if @points.length==1
|
||||
return ret
|
||||
end
|
||||
curdist=0
|
||||
distForT=@totaldist*t
|
||||
i=0
|
||||
for dist in @distances
|
||||
curdist+=dist
|
||||
if dist>0.0
|
||||
if curdist>=distForT
|
||||
distT=1.0-((curdist-distForT)/dist)
|
||||
dx=@points[i+1][0]-@points[i][0]
|
||||
dy=@points[i+1][1]-@points[i][1]
|
||||
ret=[@points[i][0]+dx*distT,
|
||||
@points[i][1]+dy*distT]
|
||||
break
|
||||
end
|
||||
end
|
||||
i+=1
|
||||
end
|
||||
return ret
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
def catmullRom(p1,p2,p3,p4,t)
|
||||
# p1=prevPoint, p2=startPoint, p3=endPoint, p4=nextPoint, t is from 0 through 1
|
||||
t2=t*t
|
||||
t3=t2*t
|
||||
return 0.5*(2*p2+t*(p3-p1) +
|
||||
t2*(2*p1-5*p2+4*p3-p4)+
|
||||
t3*(p4-3*p3+3*p2-p1))
|
||||
end
|
||||
|
||||
def getCatmullRomPoint(src,t)
|
||||
x=0,y=0
|
||||
t*=3.0
|
||||
if t<1.0
|
||||
x=catmullRom(src[0].x,src[0].x,src[1].x,src[2].x,t)
|
||||
y=catmullRom(src[0].y,src[0].y,src[1].y,src[2].y,t)
|
||||
elsif t<2.0
|
||||
t-=1.0
|
||||
x=catmullRom(src[0].x,src[1].x,src[2].x,src[3].x,t)
|
||||
y=catmullRom(src[0].y,src[1].y,src[2].y,src[3].y,t)
|
||||
else
|
||||
t-=2.0
|
||||
x=catmullRom(src[1].x,src[2].x,src[3].x,src[3].x,t)
|
||||
y=catmullRom(src[1].y,src[2].y,src[3].y,src[3].y,t)
|
||||
end
|
||||
return [x,y]
|
||||
end
|
||||
|
||||
def getCurvePoint(src,t)
|
||||
return getCatmullRomPoint(src,t)
|
||||
end
|
||||
|
||||
def curveToPointPath(curve,numpoints)
|
||||
if numpoints<2
|
||||
return nil
|
||||
end
|
||||
path=PointPath.new
|
||||
step=1.0/(numpoints-1)
|
||||
t=0.0
|
||||
numpoints.times do
|
||||
point=getCurvePoint(curve,t)
|
||||
path.addPoint(point[0],point[1])
|
||||
t+=step
|
||||
end
|
||||
return path
|
||||
end
|
||||
|
||||
def pbDefinePath(canvas)
|
||||
sliderwin2=ControlWindow.new(0,0,320,320)
|
||||
sliderwin2.viewport=canvas.viewport
|
||||
sliderwin2.addSlider(_INTL("Number of frames:"),2,500,20)
|
||||
sliderwin2.opacity=200
|
||||
defcurvebutton=sliderwin2.addButton(_INTL("Define Smooth Curve"))
|
||||
defpathbutton=sliderwin2.addButton(_INTL("Define Freehand Path"))
|
||||
okbutton=sliderwin2.addButton(_INTL("OK"))
|
||||
cancelbutton=sliderwin2.addButton(_INTL("Cancel"))
|
||||
points=[]
|
||||
path=nil
|
||||
loop do
|
||||
Graphics.update
|
||||
Input.update
|
||||
sliderwin2.update
|
||||
if sliderwin2.changed?(0) # Number of frames
|
||||
if path
|
||||
path=path.smoothPointPath(sliderwin2.value(0),false)
|
||||
i=0
|
||||
for point in path
|
||||
if i<points.length
|
||||
points[i].x=point[0]
|
||||
points[i].y=point[1]
|
||||
else
|
||||
points.push(PointSprite.new(point[0],point[1],canvas.viewport))
|
||||
end
|
||||
i+=1
|
||||
end
|
||||
for j in i...points.length
|
||||
points[j].dispose
|
||||
points[j]=nil
|
||||
end
|
||||
points.compact!
|
||||
# File.open("pointpath.txt","wb") { |f| f.write(path.inspect) }
|
||||
end
|
||||
elsif sliderwin2.changed?(defcurvebutton)
|
||||
for point in points
|
||||
point.dispose
|
||||
end
|
||||
points.clear
|
||||
30.times do
|
||||
point=PointSprite.new(0,0,canvas.viewport)
|
||||
point.visible=false
|
||||
points.push(point)
|
||||
end
|
||||
curve=[
|
||||
ControlPointSprite.new(true,canvas.viewport),
|
||||
ControlPointSprite.new(false,canvas.viewport),
|
||||
ControlPointSprite.new(false,canvas.viewport),
|
||||
ControlPointSprite.new(true,canvas.viewport)
|
||||
]
|
||||
showline=false
|
||||
sliderwin2.visible=false
|
||||
# This window displays the mouse's current position
|
||||
window=Window_UnformattedTextPokemon.new("")
|
||||
window.x=0
|
||||
window.y=320-64
|
||||
window.width=128
|
||||
window.height=64
|
||||
window.viewport=canvas.viewport
|
||||
loop do
|
||||
Graphics.update
|
||||
Input.update
|
||||
if Input.trigger?(Input::B)
|
||||
break
|
||||
end
|
||||
if Input.triggerex?(Input::LeftMouseKey)
|
||||
for j in 0...4
|
||||
next if !curve[j].hittest?
|
||||
if j==1||j==2
|
||||
next if !curve[0].visible || !curve[3].visible
|
||||
end
|
||||
curve[j].visible=true
|
||||
for k in 0...4
|
||||
curve[k].dragging=(k==j)
|
||||
end
|
||||
break
|
||||
end
|
||||
end
|
||||
for j in 0...4
|
||||
curve[j].mouseover
|
||||
end
|
||||
mouse = Mouse::getMousePos(true)
|
||||
newtext = (mouse) ? sprintf("(%d,%d)",mouse[0],mouse[1]) : "(??,??)"
|
||||
if window.text!=newtext
|
||||
window.text=newtext
|
||||
end
|
||||
if curve[0].visible && curve[3].visible &&
|
||||
!curve[0].dragging && !curve[3].dragging
|
||||
for point in points
|
||||
point.visible=true
|
||||
end
|
||||
if !showline
|
||||
curve[1].visible=true
|
||||
curve[2].visible=true
|
||||
curve[1].x=curve[0].x+0.3333*(curve[3].x-curve[0].x)
|
||||
curve[1].y=curve[0].y+0.3333*(curve[3].y-curve[0].y)
|
||||
curve[2].x=curve[0].x+0.6666*(curve[3].x-curve[0].x)
|
||||
curve[2].y=curve[0].y+0.6666*(curve[3].y-curve[0].y)
|
||||
end
|
||||
showline=true
|
||||
end
|
||||
if showline
|
||||
step=1.0/(points.length-1)
|
||||
t=0.0
|
||||
for i in 0...points.length
|
||||
point=getCurvePoint(curve,t)
|
||||
points[i].x=point[0]
|
||||
points[i].y=point[1]
|
||||
t+=step
|
||||
end
|
||||
end
|
||||
end
|
||||
window.dispose
|
||||
# dispose temporary path
|
||||
for point in points
|
||||
point.dispose
|
||||
end
|
||||
points.clear
|
||||
if showline
|
||||
path=curveToPointPath(curve,sliderwin2.value(0))
|
||||
# File.open("pointpath.txt","wb") { |f| f.write(path.inspect) }
|
||||
for point in path
|
||||
points.push(PointSprite.new(point[0],point[1],canvas.viewport))
|
||||
end
|
||||
end
|
||||
for point in curve
|
||||
point.dispose
|
||||
end
|
||||
sliderwin2.visible=true
|
||||
next
|
||||
elsif sliderwin2.changed?(defpathbutton)
|
||||
canceled=false
|
||||
pointpath=PointPath.new
|
||||
for point in points
|
||||
point.dispose
|
||||
end
|
||||
points.clear
|
||||
window=Window_UnformattedTextPokemon.newWithSize("",
|
||||
0, 320-64, 128, 64, canvas.viewport)
|
||||
sliderwin2.visible=false
|
||||
loop do
|
||||
Graphics.update
|
||||
Input.update
|
||||
if Input.trigger?(Input::ESC)
|
||||
canceled=true
|
||||
break
|
||||
end
|
||||
if Input.triggerex?(Input::LeftMouseKey)
|
||||
break
|
||||
end
|
||||
mousepos=Mouse::getMousePos(true)
|
||||
window.text = (mousepos) ? sprintf("(%d,%d)",mousepos[0],mousepos[1]) : "(??,??)"
|
||||
end
|
||||
while !canceled
|
||||
mousepos=Mouse::getMousePos(true)
|
||||
if mouse && !pointpath.isEndPoint?(mousepos[0],mousepos[1])
|
||||
pointpath.addPoint(mousepos[0],mousepos[1])
|
||||
points.push(PointSprite.new(mousepos[0],mousepos[1],canvas.viewport))
|
||||
end
|
||||
window.text = (mousepos) ? sprintf("(%d,%d)",mousepos[0],mousepos[1]) : "(??,??)"
|
||||
Graphics.update
|
||||
Input.update
|
||||
if Input.trigger?(Input::ESC) || Input.repeatcount(Input::LeftMouseKey)==0
|
||||
break
|
||||
end
|
||||
end
|
||||
window.dispose
|
||||
# dispose temporary path
|
||||
for point in points
|
||||
point.dispose
|
||||
end
|
||||
points.clear
|
||||
# generate smooth path from temporary path
|
||||
path=pointpath.smoothPointPath(sliderwin2.value(0),true)
|
||||
# redraw path from smooth path
|
||||
for point in path
|
||||
points.push(PointSprite.new(point[0],point[1],canvas.viewport))
|
||||
end
|
||||
# File.open("pointpath.txt","wb") { |f| f.write(path.inspect) }
|
||||
sliderwin2.visible=true
|
||||
next
|
||||
elsif sliderwin2.changed?(okbutton) && path
|
||||
# File.open("pointpath.txt","wb") { |f| f.write(path.inspect) }
|
||||
neededsize=canvas.currentframe+sliderwin2.value(0)
|
||||
if neededsize>canvas.animation.length
|
||||
canvas.animation.resize(neededsize)
|
||||
end
|
||||
thiscel=canvas.currentCel
|
||||
celnumber=canvas.currentcel
|
||||
for i in canvas.currentframe...neededsize
|
||||
cel=canvas.animation[i][celnumber]
|
||||
if !canvas.animation[i][celnumber]
|
||||
cel=pbCreateCel(0,0,thiscel[AnimFrame::PATTERN],canvas.animation.position)
|
||||
canvas.animation[i][celnumber]=cel
|
||||
end
|
||||
cel[AnimFrame::X]=path[i-canvas.currentframe][0]
|
||||
cel[AnimFrame::Y]=path[i-canvas.currentframe][1]
|
||||
end
|
||||
break
|
||||
elsif sliderwin2.changed?(cancelbutton) || Input.trigger?(Input::B)
|
||||
break
|
||||
end
|
||||
end
|
||||
# dispose all points
|
||||
for point in points
|
||||
point.dispose
|
||||
end
|
||||
points.clear
|
||||
sliderwin2.dispose
|
||||
return
|
||||
end
|
||||
@@ -0,0 +1,144 @@
|
||||
################################################################################
|
||||
# Importing and exporting
|
||||
################################################################################
|
||||
def pbRgssChdir(dir)
|
||||
RTP.eachPathFor(dir) { |path| Dir.chdir(path) { yield } }
|
||||
end
|
||||
|
||||
def tryLoadData(file)
|
||||
begin
|
||||
return load_data(file)
|
||||
rescue
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
||||
def dumpBase64Anim(s)
|
||||
return [Zlib::Deflate.deflate(Marshal.dump(s))].pack("m").gsub(/\n/,"\r\n")
|
||||
end
|
||||
|
||||
def loadBase64Anim(s)
|
||||
return Marshal.restore(StringInput.new(Zlib::Inflate.inflate(s.unpack("m")[0])))
|
||||
end
|
||||
|
||||
def pbExportAnim(animations)
|
||||
filename=pbMessageFreeText(_INTL("Enter a filename."),"",false,32)
|
||||
if filename!=""
|
||||
begin
|
||||
filename+=".anm"
|
||||
File.open(filename,"wb") { |f|
|
||||
f.write(dumpBase64Anim(animations[animations.selected]))
|
||||
}
|
||||
failed=false
|
||||
rescue
|
||||
pbMessage(_INTL("Couldn't save the animation to {1}.",filename))
|
||||
failed=true
|
||||
end
|
||||
if !failed
|
||||
pbMessage(_INTL("Animation was saved to {1} in the game folder.",filename))
|
||||
pbMessage(_INTL("It's a text file, so it can be transferred to others easily."))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def pbImportAnim(animations,canvas,animwin)
|
||||
animfiles=[]
|
||||
pbRgssChdir(".") {
|
||||
animfiles.concat(Dir.glob("*.anm"))
|
||||
}
|
||||
cmdwin=pbListWindow(animfiles,320)
|
||||
cmdwin.opacity=200
|
||||
cmdwin.height=480
|
||||
cmdwin.viewport=canvas.viewport
|
||||
loop do
|
||||
Graphics.update
|
||||
Input.update
|
||||
cmdwin.update
|
||||
if (Input.trigger?(Input::C) || (cmdwin.doubleclick? rescue false)) && animfiles.length>0
|
||||
begin
|
||||
textdata=loadBase64Anim(IO.read(animfiles[cmdwin.index]))
|
||||
throw "Bad data" if !textdata.is_a?(PBAnimation)
|
||||
textdata.id=-1 # this is not an RPG Maker XP animation
|
||||
pbConvertAnimToNewFormat(textdata)
|
||||
animations[animations.selected]=textdata
|
||||
rescue
|
||||
pbMessage(_INTL("The animation is invalid or could not be loaded."))
|
||||
next
|
||||
end
|
||||
graphic=animations[animations.selected].graphic
|
||||
graphic="Graphics/Animations/#{graphic}"
|
||||
if graphic && graphic!="" && !FileTest.image_exist?(graphic)
|
||||
pbMessage(_INTL("The animation file {1} was not found. The animation will load anyway.",graphic))
|
||||
end
|
||||
canvas.loadAnimation(animations[animations.selected])
|
||||
animwin.animbitmap=canvas.animbitmap
|
||||
break
|
||||
end
|
||||
if Input.trigger?(Input::B)
|
||||
break
|
||||
end
|
||||
end
|
||||
cmdwin.dispose
|
||||
return
|
||||
end
|
||||
|
||||
################################################################################
|
||||
# Format conversion
|
||||
################################################################################
|
||||
def pbConvertAnimToNewFormat(textdata)
|
||||
needconverting=false
|
||||
for i in 0...textdata.length
|
||||
next if !textdata[i]
|
||||
for j in 0...PBAnimation::MAX_SPRITES
|
||||
next if !textdata[i][j]
|
||||
needconverting=true if textdata[i][j][AnimFrame::FOCUS]==nil
|
||||
break if needconverting
|
||||
end
|
||||
break if needconverting
|
||||
end
|
||||
if needconverting
|
||||
for i in 0...textdata.length
|
||||
next if !textdata[i]
|
||||
for j in 0...PBAnimation::MAX_SPRITES
|
||||
next if !textdata[i][j]
|
||||
textdata[i][j][AnimFrame::PRIORITY]=1 if textdata[i][j][AnimFrame::PRIORITY]==nil
|
||||
if j==0 # User battler
|
||||
textdata[i][j][AnimFrame::FOCUS]=2
|
||||
textdata[i][j][AnimFrame::X]=PokeBattle_SceneConstants::FOCUSUSER_X
|
||||
textdata[i][j][AnimFrame::Y]=PokeBattle_SceneConstants::FOCUSUSER_Y
|
||||
elsif j==1 # Target battler
|
||||
textdata[i][j][AnimFrame::FOCUS]=1
|
||||
textdata[i][j][AnimFrame::X]=PokeBattle_SceneConstants::FOCUSTARGET_X
|
||||
textdata[i][j][AnimFrame::Y]=PokeBattle_SceneConstants::FOCUSTARGET_Y
|
||||
else
|
||||
textdata[i][j][AnimFrame::FOCUS]=(textdata.position || 4)
|
||||
if textdata.position==1
|
||||
textdata[i][j][AnimFrame::X]+=PokeBattle_SceneConstants::FOCUSTARGET_X
|
||||
textdata[i][j][AnimFrame::Y]+=PokeBattle_SceneConstants::FOCUSTARGET_Y-2
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
return needconverting
|
||||
end
|
||||
|
||||
def pbConvertAnimsToNewFormat
|
||||
pbMessage(_INTL("Will convert animations now."))
|
||||
count=0
|
||||
animations=pbLoadBattleAnimations
|
||||
if !animations || !animations[0]
|
||||
pbMessage(_INTL("No animations exist."))
|
||||
return
|
||||
end
|
||||
for k in 0...animations.length
|
||||
next if !animations[k]
|
||||
ret=pbConvertAnimToNewFormat(animations[k])
|
||||
count+=1 if ret
|
||||
end
|
||||
if count>0
|
||||
save_data(animations,"Data/PkmnAnimations.rxdata")
|
||||
$PokemonTemp.battleAnims = nil
|
||||
end
|
||||
pbMessage(_INTL("{1} animations converted to new format.",count))
|
||||
end
|
||||
File diff suppressed because it is too large
Load Diff
@@ -626,7 +626,7 @@ def pbEditMetadata(map_id = 0)
|
||||
GameData::MapMetadata::DATA[map_id] = GameData::MapMetadata.new(metadata_hash)
|
||||
GameData::MapMetadata.save
|
||||
end
|
||||
pbSaveMetadata
|
||||
Compiler.write_metadata
|
||||
end
|
||||
end
|
||||
|
||||
@@ -671,7 +671,7 @@ def pbItemEditor
|
||||
GameData::Item::DATA.delete(item)
|
||||
GameData::Item::DATA.delete(id_number)
|
||||
GameData::Item.save
|
||||
pbSaveItems
|
||||
Compiler.write_items
|
||||
pbMessage(_INTL("The item was deleted."))
|
||||
end
|
||||
end
|
||||
@@ -708,7 +708,7 @@ def pbItemEditor
|
||||
# Add item's data to records
|
||||
GameData::Item::DATA[itm.id_number] = GameData::Item::DATA[itm.id] = GameData::Item.new(item_hash)
|
||||
GameData::Item.save
|
||||
pbSaveItems
|
||||
Compiler.write_items
|
||||
end
|
||||
else # Add a new item
|
||||
pbItemEditorNew(nil)
|
||||
@@ -772,7 +772,7 @@ def pbItemEditorNew(default_name)
|
||||
# Add item's data to records
|
||||
GameData::Item::DATA[id_number] = GameData::Item::DATA[id.to_sym] = GameData::Item.new(item_hash)
|
||||
GameData::Item.save
|
||||
pbSaveItems
|
||||
Compiler.write_items
|
||||
pbMessage(_INTL("The item {1} was created (ID: {2}).", name, id.to_s))
|
||||
pbMessage(_ISPRINTF("Put the item's graphic (item{1:s}.png or item{2:03d}.png) in Graphics/Icons, or it will be blank.",
|
||||
id, id_number))
|
||||
@@ -857,7 +857,7 @@ def pbPokemonEditor
|
||||
GameData::Species::DATA.delete(species)
|
||||
GameData::Species::DATA.delete(id_number)
|
||||
GameData::Species.save
|
||||
pbSavePokemonData
|
||||
Compiler.write_pokemon
|
||||
pbMessage(_INTL("The species was deleted."))
|
||||
end
|
||||
end
|
||||
@@ -971,7 +971,7 @@ def pbPokemonEditor
|
||||
# Add species' data to records
|
||||
GameData::Species::DATA[spec.id_number] = GameData::Species::DATA[spec.id] = GameData::Species.new(species_hash)
|
||||
GameData::Species.save
|
||||
pbSavePokemonData
|
||||
Compiler.write_pokemon
|
||||
pbMessage(_INTL("Data saved."))
|
||||
end
|
||||
else
|
||||
@@ -1178,7 +1178,7 @@ def pbRegionalDexEditorMain
|
||||
when 0 # Save all changes to Dexes
|
||||
save_data(dex_lists, "Data/regional_dexes.dat")
|
||||
$PokemonTemp.regionalDexes = nil
|
||||
pbSaveRegionalDexes
|
||||
Compiler.write_regional_dexes
|
||||
pbMessage(_INTL("Data saved."))
|
||||
break
|
||||
when 1 # Just quit
|
||||
|
||||
@@ -1,870 +0,0 @@
|
||||
#===============================================================================
|
||||
# Save type data to PBS file
|
||||
#===============================================================================
|
||||
def pbSaveTypes
|
||||
File.open("PBS/types.txt", "wb") { |f|
|
||||
f.write(0xEF.chr)
|
||||
f.write(0xBB.chr)
|
||||
f.write(0xBF.chr)
|
||||
f.write("\# " + _INTL("See the documentation on the wiki to learn how to edit this file.") + "\r\n")
|
||||
# Write each type in turn
|
||||
GameData::Type.each do |type|
|
||||
f.write("\#-------------------------------\r\n")
|
||||
f.write("[#{type.id_number}]\r\n")
|
||||
f.write("Name = #{type.real_name}\r\n")
|
||||
f.write("InternalName = #{type.id.to_s}\r\n")
|
||||
f.write("IsPseudoType = true\r\n") if type.pseudo_type
|
||||
f.write("IsSpecialType = true\r\n") if type.special?
|
||||
f.write("Weaknesses = #{type.weaknesses.join(",")}\r\n") if type.weaknesses.length > 0
|
||||
f.write("Resistances = #{type.resistances.join(",")}\r\n") if type.resistances.length > 0
|
||||
f.write("Immunities = #{type.immunities.join(",")}\r\n") if type.immunities.length > 0
|
||||
end
|
||||
}
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Save ability data to PBS file
|
||||
#===============================================================================
|
||||
def pbSaveAbilities
|
||||
File.open("PBS/abilities.txt", "wb") { |f|
|
||||
f.write(0xEF.chr)
|
||||
f.write(0xBB.chr)
|
||||
f.write(0xBF.chr)
|
||||
f.write("\# " + _INTL("See the documentation on the wiki to learn how to edit this file.") + "\r\n")
|
||||
f.write("\#-------------------------------\r\n")
|
||||
GameData::Ability.each do |a|
|
||||
f.write(sprintf("%d,%s,%s,%s\r\n",
|
||||
a.id_number,
|
||||
csvQuote(a.id.to_s),
|
||||
csvQuote(a.real_name),
|
||||
csvQuoteAlways(a.real_description)
|
||||
))
|
||||
end
|
||||
}
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Save move data to PBS file
|
||||
#===============================================================================
|
||||
def pbSaveMoveData
|
||||
File.open("PBS/moves.txt", "wb") { |f|
|
||||
f.write(0xEF.chr)
|
||||
f.write(0xBB.chr)
|
||||
f.write(0xBF.chr)
|
||||
f.write("\# " + _INTL("See the documentation on the wiki to learn how to edit this file.") + "\r\n")
|
||||
current_type = -1
|
||||
GameData::Move.each do |m|
|
||||
if current_type != m.type
|
||||
current_type = m.type
|
||||
f.write("\#-------------------------------\r\n")
|
||||
end
|
||||
f.write(sprintf("%d,%s,%s,%s,%d,%s,%s,%d,%d,%d,%s,%d,%s,%s\r\n",
|
||||
m.id_number,
|
||||
csvQuote(m.id.to_s),
|
||||
csvQuote(m.real_name),
|
||||
csvQuote(m.function_code),
|
||||
m.base_damage,
|
||||
m.type.to_s,
|
||||
["Physical", "Special", "Status"][m.category],
|
||||
m.accuracy,
|
||||
m.total_pp,
|
||||
m.effect_chance,
|
||||
(getConstantName(PBTargets, m.target) rescue sprintf("%d", m.target)),
|
||||
m.priority,
|
||||
csvQuote(m.flags),
|
||||
csvQuoteAlways(m.real_description)
|
||||
))
|
||||
end
|
||||
}
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Save map connection data to PBS file
|
||||
#===============================================================================
|
||||
def normalizeConnectionPoint(conn)
|
||||
ret = conn.clone
|
||||
if conn[1]<0 && conn[4]<0
|
||||
elsif conn[1]<0 || conn[4]<0
|
||||
ret[4] = -conn[1]
|
||||
ret[1] = -conn[4]
|
||||
end
|
||||
if conn[2]<0 && conn[5]<0
|
||||
elsif conn[2]<0 || conn[5]<0
|
||||
ret[5] = -conn[2]
|
||||
ret[2] = -conn[5]
|
||||
end
|
||||
return ret
|
||||
end
|
||||
|
||||
def writeConnectionPoint(map1,x1,y1,map2,x2,y2)
|
||||
dims1 = MapFactoryHelper.getMapDims(map1)
|
||||
dims2 = MapFactoryHelper.getMapDims(map2)
|
||||
if x1==0 && x2==dims2[0]
|
||||
return sprintf("%d,West,%d,%d,East,%d",map1,y1,map2,y2)
|
||||
elsif y1==0 && y2==dims2[1]
|
||||
return sprintf("%d,North,%d,%d,South,%d",map1,x1,map2,x2)
|
||||
elsif x1==dims1[0] && x2==0
|
||||
return sprintf("%d,East,%d,%d,West,%d",map1,y1,map2,y2)
|
||||
elsif y1==dims1[1] && y2==0
|
||||
return sprintf("%d,South,%d,%d,North,%d",map1,x1,map2,x2)
|
||||
end
|
||||
return sprintf("%d,%d,%d,%d,%d,%d",map1,x1,y1,map2,x2,y2)
|
||||
end
|
||||
|
||||
def pbSerializeConnectionData(conndata,mapinfos)
|
||||
File.open("PBS/connections.txt","wb") { |f|
|
||||
f.write(0xEF.chr)
|
||||
f.write(0xBB.chr)
|
||||
f.write(0xBF.chr)
|
||||
f.write("\# " + _INTL("See the documentation on the wiki to learn how to edit this file.") + "\r\n")
|
||||
f.write("\#-------------------------------\r\n")
|
||||
for conn in conndata
|
||||
if mapinfos
|
||||
# Skip if map no longer exists
|
||||
next if !mapinfos[conn[0]] || !mapinfos[conn[3]]
|
||||
f.write(sprintf("# %s (%d) - %s (%d)\r\n",
|
||||
mapinfos[conn[0]] ? mapinfos[conn[0]].name : "???",conn[0],
|
||||
mapinfos[conn[3]] ? mapinfos[conn[3]].name : "???",conn[3]))
|
||||
end
|
||||
if conn[1].is_a?(String) || conn[4].is_a?(String)
|
||||
f.write(sprintf("%d,%s,%d,%d,%s,%d",conn[0],conn[1],
|
||||
conn[2],conn[3],conn[4],conn[5]))
|
||||
else
|
||||
ret = normalizeConnectionPoint(conn)
|
||||
f.write(writeConnectionPoint(ret[0],ret[1],ret[2],ret[3],ret[4],ret[5]))
|
||||
end
|
||||
f.write("\r\n")
|
||||
end
|
||||
}
|
||||
save_data(conndata,"Data/map_connections.dat")
|
||||
end
|
||||
|
||||
def pbSaveConnectionData
|
||||
data = load_data("Data/map_connections.dat") rescue nil
|
||||
return if !data
|
||||
pbSerializeConnectionData(data,pbLoadRxData("Data/MapInfos"))
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Save metadata data to PBS file
|
||||
#===============================================================================
|
||||
def pbSaveMetadata
|
||||
File.open("PBS/metadata.txt", "wb") { |f|
|
||||
f.write(0xEF.chr)
|
||||
f.write(0xBB.chr)
|
||||
f.write(0xBF.chr)
|
||||
f.write("\# " + _INTL("See the documentation on the wiki to learn how to edit this file.") + "\r\n")
|
||||
# Write global metadata
|
||||
f.write("\#-------------------------------\r\n")
|
||||
f.write("[000]\r\n")
|
||||
metadata = GameData::Metadata.get
|
||||
schema = GameData::Metadata::SCHEMA
|
||||
keys = schema.keys.sort {|a, b| schema[a][0] <=> schema[b][0] }
|
||||
for key in keys
|
||||
record = metadata.property_from_string(key)
|
||||
next if record.nil?
|
||||
f.write(sprintf("%s = ", key))
|
||||
pbWriteCsvRecord(record, f, schema[key])
|
||||
f.write("\r\n")
|
||||
end
|
||||
# Write map metadata
|
||||
map_infos = pbLoadRxData("Data/MapInfos")
|
||||
schema = GameData::MapMetadata::SCHEMA
|
||||
keys = schema.keys.sort {|a, b| schema[a][0] <=> schema[b][0] }
|
||||
GameData::MapMetadata.each do |map_data|
|
||||
f.write("\#-------------------------------\r\n")
|
||||
f.write(sprintf("[%03d]\r\n", map_data.id))
|
||||
if map_infos && map_infos[map_data.id]
|
||||
f.write(sprintf("# %s\r\n", map_infos[map_data.id].name))
|
||||
end
|
||||
for key in keys
|
||||
record = map_data.property_from_string(key)
|
||||
next if record.nil?
|
||||
f.write(sprintf("%s = ", key))
|
||||
pbWriteCsvRecord(record, f, schema[key])
|
||||
f.write("\r\n")
|
||||
end
|
||||
end
|
||||
}
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Save item data to PBS file
|
||||
#===============================================================================
|
||||
def pbSaveItems
|
||||
File.open("PBS/items.txt", "wb") { |f|
|
||||
f.write(0xEF.chr)
|
||||
f.write(0xBB.chr)
|
||||
f.write(0xBF.chr)
|
||||
f.write("\# " + _INTL("See the documentation on the wiki to learn how to edit this file.") + "\r\n")
|
||||
current_pocket = 0
|
||||
GameData::Item.each do |i|
|
||||
if current_pocket != i.pocket
|
||||
current_pocket = i.pocket
|
||||
f.write("\#-------------------------------\r\n")
|
||||
end
|
||||
move_name = (i.move) ? GameData::Move.get(i.move).id.to_s : ""
|
||||
sprintf_text = "%d,%s,%s,%s,%d,%d,%s,%d,%d,%d\r\n"
|
||||
sprintf_text = "%d,%s,%s,%s,%d,%d,%s,%d,%d,%d,%s\r\n" if move_name != ""
|
||||
f.write(sprintf(sprintf_text,
|
||||
i.id_number,
|
||||
csvQuote(i.id.to_s),
|
||||
csvQuote(i.real_name),
|
||||
csvQuote(i.real_name_plural),
|
||||
i.pocket,
|
||||
i.price,
|
||||
csvQuoteAlways(i.real_description),
|
||||
i.field_use,
|
||||
i.battle_use,
|
||||
i.type,
|
||||
csvQuote(move_name)
|
||||
))
|
||||
end
|
||||
}
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Save berry plant data to PBS file
|
||||
#===============================================================================
|
||||
def pbSaveBerryPlants
|
||||
File.open("PBS/berryplants.txt", "wb") { |f|
|
||||
f.write(0xEF.chr)
|
||||
f.write(0xBB.chr)
|
||||
f.write(0xBF.chr)
|
||||
f.write("\# " + _INTL("See the documentation on the wiki to learn how to edit this file.") + "\r\n")
|
||||
f.write("\#-------------------------------\r\n")
|
||||
GameData::BerryPlant.each do |bp|
|
||||
f.write(sprintf("%s = %d,%d,%d,%d\r\n",
|
||||
csvQuote(bp.id.to_s),
|
||||
bp.hours_per_stage,
|
||||
bp.drying_per_hour,
|
||||
bp.minimum_yield,
|
||||
bp.maximum_yield
|
||||
))
|
||||
end
|
||||
}
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Save trainer list data to PBS file
|
||||
#===============================================================================
|
||||
def pbSaveTrainerLists
|
||||
trainerlists = load_data("Data/trainer_lists.dat") rescue nil
|
||||
return if !trainerlists
|
||||
File.open("PBS/trainerlists.txt","wb") { |f|
|
||||
f.write(0xEF.chr)
|
||||
f.write(0xBB.chr)
|
||||
f.write(0xBF.chr)
|
||||
f.write("\# " + _INTL("See the documentation on the wiki to learn how to edit this file.") + "\r\n")
|
||||
for tr in trainerlists
|
||||
f.write("\#-------------------------------\r\n")
|
||||
f.write(((tr[5]) ? "[DefaultTrainerList]" : "[TrainerList]")+"\r\n")
|
||||
f.write("Trainers = "+tr[3]+"\r\n")
|
||||
f.write("Pokemon = "+tr[4]+"\r\n")
|
||||
f.write("Challenges = "+tr[2].join(",")+"\r\n") if !tr[5]
|
||||
pbSaveBTTrainers(tr[0],"PBS/"+tr[3])
|
||||
pbSaveBattlePokemon(tr[1],"PBS/"+tr[4])
|
||||
end
|
||||
}
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Save wild encounter data to PBS file
|
||||
#===============================================================================
|
||||
def pbSaveEncounterData
|
||||
encdata = pbLoadEncountersData
|
||||
return if !encdata
|
||||
mapinfos = pbLoadRxData("Data/MapInfos")
|
||||
File.open("PBS/encounters.txt","wb") { |f|
|
||||
f.write(0xEF.chr)
|
||||
f.write(0xBB.chr)
|
||||
f.write(0xBF.chr)
|
||||
f.write("\# " + _INTL("See the documentation on the wiki to learn how to edit this file.") + "\r\n")
|
||||
sortedkeys = encdata.keys.sort
|
||||
for i in sortedkeys
|
||||
next if !encdata[i]
|
||||
e = encdata[i]
|
||||
mapname = ""
|
||||
if mapinfos[i]
|
||||
map = mapinfos[i].name
|
||||
mapname = " # #{map}"
|
||||
end
|
||||
f.write("\#-------------------------------\r\n")
|
||||
f.write(sprintf("%03d%s\r\n",i,mapname))
|
||||
f.write(sprintf("%d,%d,%d\r\n",e[0][EncounterTypes::Land],
|
||||
e[0][EncounterTypes::Cave],e[0][EncounterTypes::Water]))
|
||||
for j in 0...e[1].length
|
||||
enc = e[1][j]
|
||||
next if !enc
|
||||
f.write(sprintf("%s\r\n",EncounterTypes::Names[j]))
|
||||
for k in 0...EncounterTypes::EnctypeChances[j].length
|
||||
next if !enc[k]
|
||||
encentry = enc[k]
|
||||
if encentry[1]==encentry[2]
|
||||
f.write(sprintf(" %s,%d\r\n",encentry[0],encentry[1]))
|
||||
else
|
||||
f.write(sprintf(" %s,%d,%d\r\n",encentry[0],encentry[1],encentry[2]))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
}
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Save trainer type data to PBS file
|
||||
#===============================================================================
|
||||
def pbSaveTrainerTypes
|
||||
File.open("PBS/trainertypes.txt", "wb") { |f|
|
||||
f.write(0xEF.chr)
|
||||
f.write(0xBB.chr)
|
||||
f.write(0xBF.chr)
|
||||
f.write("\# " + _INTL("See the documentation on the wiki to learn how to edit this file.") + "\r\n")
|
||||
f.write("\#-------------------------------\r\n")
|
||||
GameData::TrainerType.each do |t|
|
||||
f.write(sprintf("%d,%s,%s,%d,%s,%s,%s,%s,%s,%s\r\n",
|
||||
t.id_number,
|
||||
csvQuote(t.id.to_s),
|
||||
csvQuote(t.real_name),
|
||||
t.base_money,
|
||||
csvQuote(t.battle_BGM),
|
||||
csvQuote(t.victory_ME),
|
||||
csvQuote(t.intro_ME),
|
||||
["Male", "Female", "Mixed"][t.gender],
|
||||
(t.skill_level == t.base_money) ? "" : t.skill_level.to_s,
|
||||
csvQuote(t.skill_code)
|
||||
))
|
||||
end
|
||||
}
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Save individual trainer data to PBS file
|
||||
#===============================================================================
|
||||
def pbSaveTrainerBattles
|
||||
data = pbLoadTrainersData
|
||||
return if !data
|
||||
File.open("PBS/trainers.txt","wb") { |f|
|
||||
f.write(0xEF.chr)
|
||||
f.write(0xBB.chr)
|
||||
f.write(0xBF.chr)
|
||||
f.write("\# " + _INTL("See the documentation on the wiki to learn how to edit this file.") + "\r\n")
|
||||
for trainer in data
|
||||
trtypename = trainer[0].to_s
|
||||
next if !trtypename
|
||||
f.write("\#-------------------------------\r\n")
|
||||
# Section
|
||||
trainername = trainer[1] ? trainer[1].gsub(/,/,";") : "???"
|
||||
if trainer[4]==0
|
||||
f.write(sprintf("[%s,%s]\r\n",trtypename,trainername))
|
||||
else
|
||||
f.write(sprintf("[%s,%s,%d]\r\n",trtypename,trainername,trainer[4]))
|
||||
end
|
||||
# Trainer's items
|
||||
if trainer[2] && trainer[2].length>0
|
||||
itemstring = ""
|
||||
for i in 0...trainer[2].length
|
||||
itemstring.concat(",") if i > 0
|
||||
itemstring.concat(trainer[2][i].to_s)
|
||||
end
|
||||
f.write(sprintf("Items = %s\r\n",itemstring)) if itemstring!=""
|
||||
end
|
||||
# Lose texts
|
||||
if trainer[5] && trainer[5]!=""
|
||||
f.write(sprintf("LoseText = %s\r\n",csvQuoteAlways(trainer[5])))
|
||||
end
|
||||
# Pokémon
|
||||
for poke in trainer[3]
|
||||
f.write(sprintf("Pokemon = %s,%d\r\n",poke[TrainerData::SPECIES],poke[TrainerData::LEVEL]))
|
||||
if poke[TrainerData::NAME] && poke[TrainerData::NAME]!=""
|
||||
f.write(sprintf(" Name = %s\r\n",poke[TrainerData::NAME]))
|
||||
end
|
||||
if poke[TrainerData::FORM]
|
||||
f.write(sprintf(" Form = %d\r\n",poke[TrainerData::FORM]))
|
||||
end
|
||||
if poke[TrainerData::GENDER]
|
||||
f.write(sprintf(" Gender = %s\r\n",(poke[TrainerData::GENDER]==1) ? "female" : "male"))
|
||||
end
|
||||
if poke[TrainerData::SHINY]
|
||||
f.write(" Shiny = yes\r\n")
|
||||
end
|
||||
if poke[TrainerData::SHADOW]
|
||||
f.write(" Shadow = yes\r\n")
|
||||
end
|
||||
if poke[TrainerData::MOVES] && poke[TrainerData::MOVES].length>0
|
||||
movestring = ""
|
||||
for i in 0...poke[TrainerData::MOVES].length
|
||||
movename = GameData::Move.get(poke[TrainerData::MOVES][i]).id.to_s
|
||||
next if !movename
|
||||
movestring.concat(",") if i>0
|
||||
movestring.concat(movename)
|
||||
end
|
||||
f.write(sprintf(" Moves = %s\r\n",movestring)) if movestring!=""
|
||||
end
|
||||
if poke[TrainerData::ABILITY]
|
||||
f.write(sprintf(" Ability = %s\r\n",poke[TrainerData::ABILITY].to_s))
|
||||
end
|
||||
if poke[TrainerData::ITEM]
|
||||
f.write(sprintf(" Item = %s\r\n",poke[TrainerData::ITEM].to_s))
|
||||
end
|
||||
if poke[TrainerData::NATURE]
|
||||
nature = getConstantName(PBNatures,poke[TrainerData::NATURE]) rescue nil
|
||||
f.write(sprintf(" Nature = %s\r\n",nature)) if nature
|
||||
end
|
||||
if poke[TrainerData::IV] && poke[TrainerData::IV].length>0
|
||||
f.write(sprintf(" IV = %d",poke[TrainerData::IV][0]))
|
||||
if poke[TrainerData::IV].length>1
|
||||
for i in 1...6
|
||||
f.write(sprintf(",%d",(i<poke[TrainerData::IV].length) ? poke[TrainerData::IV][i] : poke[TrainerData::IV][0]))
|
||||
end
|
||||
end
|
||||
f.write("\r\n")
|
||||
end
|
||||
if poke[TrainerData::EV] && poke[TrainerData::EV].length>0
|
||||
f.write(sprintf(" EV = %d",poke[TrainerData::EV][0]))
|
||||
if poke[TrainerData::EV].length>1
|
||||
for i in 1...6
|
||||
f.write(sprintf(",%d",(i<poke[TrainerData::EV].length) ? poke[TrainerData::EV][i] : poke[TrainerData::EV][0]))
|
||||
end
|
||||
end
|
||||
f.write("\r\n")
|
||||
end
|
||||
if poke[TrainerData::HAPPINESS]
|
||||
f.write(sprintf(" Happiness = %d\r\n",poke[TrainerData::HAPPINESS]))
|
||||
end
|
||||
if poke[TrainerData::BALL]
|
||||
f.write(sprintf(" Ball = %d\r\n",poke[TrainerData::BALL]))
|
||||
end
|
||||
end
|
||||
end
|
||||
}
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Save Town Map data to PBS file
|
||||
#===============================================================================
|
||||
def pbSaveTownMap
|
||||
mapdata = pbLoadTownMapData
|
||||
return if !mapdata
|
||||
File.open("PBS/townmap.txt","wb") { |f|
|
||||
f.write(0xEF.chr)
|
||||
f.write(0xBB.chr)
|
||||
f.write(0xBF.chr)
|
||||
f.write("\# " + _INTL("See the documentation on the wiki to learn how to edit this file.") + "\r\n")
|
||||
for i in 0...mapdata.length
|
||||
map = mapdata[i]
|
||||
next if !map
|
||||
f.write("\#-------------------------------\r\n")
|
||||
f.write(sprintf("[%d]\r\n",i))
|
||||
rname = pbGetMessage(MessageTypes::RegionNames,i)
|
||||
f.write(sprintf("Name = %s\r\nFilename = %s\r\n",
|
||||
(rname && rname!="") ? rname : _INTL("Unnamed"),
|
||||
csvQuote((map[1].is_a?(Array)) ? map[1][0] : map[1])))
|
||||
for loc in map[2]
|
||||
f.write("Point = ")
|
||||
pbWriteCsvRecord(loc,f,[nil,"uussUUUU"])
|
||||
f.write("\r\n")
|
||||
end
|
||||
end
|
||||
}
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Save phone message data to PBS file
|
||||
#===============================================================================
|
||||
def pbSavePhoneData
|
||||
data = load_data("Data/phone.dat") rescue nil
|
||||
return if !data
|
||||
File.open("PBS/phone.txt","wb") { |f|
|
||||
f.write(0xEF.chr)
|
||||
f.write(0xBB.chr)
|
||||
f.write(0xBF.chr)
|
||||
f.write("\# " + _INTL("See the documentation on the wiki to learn how to edit this file.") + "\r\n")
|
||||
f.write("\#-------------------------------\r\n")
|
||||
f.write("[<Generics>]\r\n")
|
||||
f.write(data.generics.join("\r\n")+"\r\n")
|
||||
f.write("\#-------------------------------\r\n")
|
||||
f.write("[<BattleRequests>]\r\n")
|
||||
f.write(data.battleRequests.join("\r\n")+"\r\n")
|
||||
f.write("\#-------------------------------\r\n")
|
||||
f.write("[<GreetingsMorning>]\r\n")
|
||||
f.write(data.greetingsMorning.join("\r\n")+"\r\n")
|
||||
f.write("\#-------------------------------\r\n")
|
||||
f.write("[<GreetingsEvening>]\r\n")
|
||||
f.write(data.greetingsEvening.join("\r\n")+"\r\n")
|
||||
f.write("\#-------------------------------\r\n")
|
||||
f.write("[<Greetings>]\r\n")
|
||||
f.write(data.greetings.join("\r\n")+"\r\n")
|
||||
f.write("\#-------------------------------\r\n")
|
||||
f.write("[<Bodies1>]\r\n")
|
||||
f.write(data.bodies1.join("\r\n")+"\r\n")
|
||||
f.write("\#-------------------------------\r\n")
|
||||
f.write("[<Bodies2>]\r\n")
|
||||
f.write(data.bodies2.join("\r\n")+"\r\n")
|
||||
}
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Save Pokémon data to PBS file
|
||||
#===============================================================================
|
||||
def pbSavePokemonData
|
||||
File.open("PBS/pokemon.txt", "wb") { |f|
|
||||
f.write(0xEF.chr)
|
||||
f.write(0xBB.chr)
|
||||
f.write(0xBF.chr)
|
||||
f.write("\# " + _INTL("See the documentation on the wiki to learn how to edit this file.") + "\r\n")
|
||||
GameData::Species.each do |species|
|
||||
next if species.form != 0
|
||||
pbSetWindowText(_INTL("Writing species {1}...", species.id_number))
|
||||
Graphics.update if species.id_number % 50 == 0
|
||||
f.write("\#-------------------------------\r\n")
|
||||
f.write(sprintf("[%d]\r\n", species.id_number))
|
||||
f.write(sprintf("Name = %s\r\n", species.real_name))
|
||||
f.write(sprintf("InternalName = %s\r\n", species.species))
|
||||
f.write(sprintf("Type1 = %s\r\n", species.type1))
|
||||
f.write(sprintf("Type2 = %s\r\n", species.type2)) if species.type2 != species.type1
|
||||
f.write(sprintf("BaseStats = %s\r\n", species.base_stats.join(",")))
|
||||
f.write(sprintf("GenderRate = %s\r\n", getConstantName(PBGenderRates, species.gender_rate)))
|
||||
f.write(sprintf("GrowthRate = %s\r\n", getConstantName(PBGrowthRates, species.growth_rate)))
|
||||
f.write(sprintf("BaseEXP = %d\r\n", species.base_exp))
|
||||
f.write(sprintf("EffortPoints = %s\r\n", species.evs.join(",")))
|
||||
f.write(sprintf("Rareness = %d\r\n", species.catch_rate))
|
||||
f.write(sprintf("Happiness = %d\r\n", species.happiness))
|
||||
if species.abilities.length > 0
|
||||
f.write(sprintf("Abilities = %s\r\n", species.abilities.join(",")))
|
||||
end
|
||||
if species.hidden_abilities.length > 0
|
||||
f.write(sprintf("HiddenAbility = %s\r\n", species.hidden_abilities.join(",")))
|
||||
end
|
||||
if species.moves.length > 0
|
||||
f.write(sprintf("Moves = %s\r\n", species.moves.join(",")))
|
||||
end
|
||||
if species.tutor_moves.length > 0
|
||||
f.write(sprintf("TutorMoves = %s\r\n", species.tutor_moves.join(",")))
|
||||
end
|
||||
if species.egg_moves.length > 0
|
||||
f.write(sprintf("EggMoves = %s\r\n", species.egg_moves.join(",")))
|
||||
end
|
||||
if species.egg_groups.length > 0
|
||||
f.write("Compatibility = ")
|
||||
species.egg_groups.each_with_index do |group, i|
|
||||
f.write(",") if i > 0
|
||||
f.write(getConstantName(PBEggGroups, group))
|
||||
end
|
||||
f.write("\r\n")
|
||||
end
|
||||
f.write(sprintf("StepsToHatch = %d\r\n", species.hatch_steps))
|
||||
f.write(sprintf("Height = %.1f\r\n", species.height / 10.0))
|
||||
f.write(sprintf("Weight = %.1f\r\n", species.weight / 10.0))
|
||||
f.write(sprintf("Color = %s\r\n", getConstantName(PBColors, species.color)))
|
||||
f.write(sprintf("Shape = %d\r\n", species.shape))
|
||||
f.write(sprintf("Habitat = %s\r\n", getConstantName(PBHabitats, species.habitat))) if species.habitat != PBHabitats::None
|
||||
f.write(sprintf("Kind = %s\r\n", species.real_category))
|
||||
f.write(sprintf("Pokedex = %s\r\n", species.real_pokedex_entry))
|
||||
f.write(sprintf("FormName = %s\r\n", species.real_form_name)) if species.real_form_name && !species.real_form_name.empty?
|
||||
f.write(sprintf("Generation = %d\r\n", species.generation)) if species.generation != 0
|
||||
f.write(sprintf("WildItemCommon = %s\r\n", species.wild_item_common)) if species.wild_item_common
|
||||
f.write(sprintf("WildItemUncommon = %s\r\n", species.wild_item_uncommon)) if species.wild_item_uncommon
|
||||
f.write(sprintf("WildItemRare = %s\r\n", species.wild_item_rare)) if species.wild_item_rare
|
||||
f.write(sprintf("BattlerPlayerX = %d\r\n", species.back_sprite_x))
|
||||
f.write(sprintf("BattlerPlayerY = %d\r\n", species.back_sprite_y))
|
||||
f.write(sprintf("BattlerEnemyX = %d\r\n", species.front_sprite_x))
|
||||
f.write(sprintf("BattlerEnemyY = %d\r\n", species.front_sprite_y))
|
||||
f.write(sprintf("BattlerAltitude = %d\r\n", species.front_sprite_altitude)) if species.front_sprite_altitude != 0
|
||||
f.write(sprintf("BattlerShadowX = %d\r\n", species.shadow_x))
|
||||
f.write(sprintf("BattlerShadowSize = %d\r\n", species.shadow_size))
|
||||
if species.evolutions.any? { |evo| !evo[3] }
|
||||
f.write("Evolutions = ")
|
||||
need_comma = false
|
||||
species.evolutions.each do |evo|
|
||||
next if evo[3] # Skip prevolution entries
|
||||
f.write(",") if need_comma
|
||||
need_comma = true
|
||||
f.write(sprintf("%s,%s,", evo[0], getConstantName(PBEvolution, evo[1])))
|
||||
param_type = PBEvolution.getFunction(evo[1], "parameterType")
|
||||
has_param = !PBEvolution.hasFunction?(evo[1], "parameterType") || param_type != nil
|
||||
next if !has_param
|
||||
if param_type
|
||||
if GameData.const_defined?(param_type.to_sym)
|
||||
f.write(evo[2].to_s)
|
||||
else
|
||||
f.write(getConstantName(param_type, evo[2]))
|
||||
end
|
||||
else
|
||||
f.write(evo[2].to_s)
|
||||
end
|
||||
end
|
||||
f.write("\r\n")
|
||||
end
|
||||
f.write(sprintf("Incense = %s\r\n", species.incense)) if species.incense
|
||||
end
|
||||
}
|
||||
Graphics.update
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Save Pokémon forms data to PBS file
|
||||
#===============================================================================
|
||||
def pbSavePokemonFormsData
|
||||
File.open("PBS/pokemonforms.txt", "wb") { |f|
|
||||
f.write(0xEF.chr)
|
||||
f.write(0xBB.chr)
|
||||
f.write(0xBF.chr)
|
||||
f.write("\# " + _INTL("See the documentation on the wiki to learn how to edit this file.") + "\r\n")
|
||||
GameData::Species.each do |species|
|
||||
next if species.form == 0
|
||||
base_species = GameData::Species.get(species.species)
|
||||
pbSetWindowText(_INTL("Writing species {1}...", species.id_number))
|
||||
Graphics.update if species.id_number % 50 == 0
|
||||
f.write("\#-------------------------------\r\n")
|
||||
f.write(sprintf("[%s,%d]\r\n", species.species, species.form))
|
||||
f.write(sprintf("FormName = %s\r\n", species.real_form_name)) if species.real_form_name && !species.real_form_name.empty?
|
||||
f.write(sprintf("PokedexForm = %d\r\n", species.pokedex_form)) if species.pokedex_form != species.form
|
||||
f.write(sprintf("MegaStone = %s\r\n", species.mega_stone)) if species.mega_stone
|
||||
f.write(sprintf("MegaMove = %s\r\n", species.mega_move)) if species.mega_move
|
||||
f.write(sprintf("UnmegaForm = %d\r\n", species.unmega_form)) if species.unmega_form != 0
|
||||
f.write(sprintf("MegaMessage = %d\r\n", species.mega_message)) if species.mega_message != 0
|
||||
if species.type1 != base_species.type1 || species.type2 != base_species.type2
|
||||
f.write(sprintf("Type1 = %s\r\n", species.type1))
|
||||
f.write(sprintf("Type2 = %s\r\n", species.type2)) if species.type2 != species.type1
|
||||
end
|
||||
f.write(sprintf("BaseStats = %s\r\n", species.base_stats.join(","))) if species.base_stats != base_species.base_stats
|
||||
f.write(sprintf("BaseEXP = %d\r\n", species.base_exp)) if species.base_exp != base_species.base_exp
|
||||
f.write(sprintf("EffortPoints = %s\r\n", species.evs.join(","))) if species.evs != base_species.evs
|
||||
f.write(sprintf("Rareness = %d\r\n", species.catch_rate)) if species.catch_rate != base_species.catch_rate
|
||||
f.write(sprintf("Happiness = %d\r\n", species.happiness)) if species.happiness != base_species.happiness
|
||||
if species.abilities.length > 0 && species.abilities != base_species.abilities
|
||||
f.write(sprintf("Abilities = %s\r\n", species.abilities.join(",")))
|
||||
end
|
||||
if species.hidden_abilities.length > 0 && species.hidden_abilities != base_species.hidden_abilities
|
||||
f.write(sprintf("HiddenAbility = %s\r\n", species.hidden_abilities.join(",")))
|
||||
end
|
||||
if species.moves.length > 0 && species.moves != base_species.moves
|
||||
f.write(sprintf("Moves = %s\r\n", species.moves.join(",")))
|
||||
end
|
||||
if species.tutor_moves.length > 0 && species.tutor_moves != base_species.tutor_moves
|
||||
f.write(sprintf("TutorMoves = %s\r\n", species.tutor_moves.join(",")))
|
||||
end
|
||||
if species.egg_moves.length > 0 && species.egg_moves != base_species.egg_moves
|
||||
f.write(sprintf("EggMoves = %s\r\n", species.egg_moves.join(",")))
|
||||
end
|
||||
if species.egg_groups.length > 0 && species.egg_groups != base_species.egg_groups
|
||||
f.write("Compatibility = ")
|
||||
species.egg_groups.each_with_index do |group, i|
|
||||
f.write(",") if i > 0
|
||||
f.write(getConstantName(PBEggGroups, group))
|
||||
end
|
||||
f.write("\r\n")
|
||||
end
|
||||
f.write(sprintf("StepsToHatch = %d\r\n", species.hatch_steps)) if species.hatch_steps != base_species.hatch_steps
|
||||
f.write(sprintf("Height = %.1f\r\n", species.height / 10.0)) if species.height != base_species.height
|
||||
f.write(sprintf("Weight = %.1f\r\n", species.weight / 10.0)) if species.weight != base_species.weight
|
||||
f.write(sprintf("Color = %s\r\n", getConstantName(PBColors, species.color))) if species.color != base_species.color
|
||||
f.write(sprintf("Shape = %d\r\n", species.shape)) if species.shape != base_species.shape
|
||||
if species.habitat != PBHabitats::None && species.habitat != base_species.habitat
|
||||
f.write(sprintf("Habitat = %s\r\n", getConstantName(PBHabitats, species.habitat)))
|
||||
end
|
||||
f.write(sprintf("Kind = %s\r\n", species.real_category)) if species.real_category != base_species.real_category
|
||||
f.write(sprintf("Pokedex = %s\r\n", species.real_pokedex_entry)) if species.real_pokedex_entry != base_species.real_pokedex_entry
|
||||
f.write(sprintf("Generation = %d\r\n", species.generation)) if species.generation != base_species.generation
|
||||
if species.wild_item_common != base_species.wild_item_common ||
|
||||
species.wild_item_uncommon != base_species.wild_item_uncommon ||
|
||||
species.wild_item_rare != base_species.wild_item_rare
|
||||
f.write(sprintf("WildItemCommon = %s\r\n", species.wild_item_common)) if species.wild_item_common
|
||||
f.write(sprintf("WildItemUncommon = %s\r\n", species.wild_item_uncommon)) if species.wild_item_uncommon
|
||||
f.write(sprintf("WildItemRare = %s\r\n", species.wild_item_rare)) if species.wild_item_rare
|
||||
end
|
||||
f.write(sprintf("BattlerPlayerX = %d\r\n", species.back_sprite_x)) if species.back_sprite_x != base_species.back_sprite_x
|
||||
f.write(sprintf("BattlerPlayerY = %d\r\n", species.back_sprite_y)) if species.back_sprite_y != base_species.back_sprite_y
|
||||
f.write(sprintf("BattlerEnemyX = %d\r\n", species.front_sprite_x)) if species.front_sprite_x != base_species.front_sprite_x
|
||||
f.write(sprintf("BattlerEnemyY = %d\r\n", species.front_sprite_y)) if species.front_sprite_y != base_species.front_sprite_y
|
||||
f.write(sprintf("BattlerAltitude = %d\r\n", species.front_sprite_altitude)) if species.front_sprite_altitude != base_species.front_sprite_altitude
|
||||
f.write(sprintf("BattlerShadowX = %d\r\n", species.shadow_x)) if species.shadow_x != base_species.shadow_x
|
||||
f.write(sprintf("BattlerShadowSize = %d\r\n", species.shadow_size)) if species.shadow_size != base_species.shadow_size
|
||||
if species.evolutions != base_species.evolutions && species.evolutions.any? { |evo| !evo[3] }
|
||||
f.write("Evolutions = ")
|
||||
need_comma = false
|
||||
species.evolutions.each do |evo|
|
||||
next if evo[3] # Skip prevolution entries
|
||||
f.write(",") if need_comma
|
||||
need_comma = true
|
||||
f.write(sprintf("%s,%s,", evo[0], getConstantName(PBEvolution, evo[1])))
|
||||
param_type = PBEvolution.getFunction(evo[1], "parameterType")
|
||||
has_param = !PBEvolution.hasFunction?(evo[1], "parameterType") || param_type != nil
|
||||
next if !has_param
|
||||
if param_type
|
||||
if GameData.const_defined?(param_type.to_sym)
|
||||
f.write(evo[2].to_s)
|
||||
else
|
||||
f.write(getConstantName(param_type, evo[2]))
|
||||
end
|
||||
else
|
||||
f.write(evo[2].to_s)
|
||||
end
|
||||
end
|
||||
f.write("\r\n")
|
||||
end
|
||||
end
|
||||
}
|
||||
Graphics.update
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Save Shadow move data to PBS file
|
||||
#===============================================================================
|
||||
def pbSaveShadowMoves
|
||||
shadow_movesets = pbLoadShadowMovesets
|
||||
File.open("PBS/shadowmoves.txt", "wb") { |f|
|
||||
f.write(0xEF.chr)
|
||||
f.write(0xBB.chr)
|
||||
f.write(0xBF.chr)
|
||||
f.write("\# " + _INTL("See the documentation on the wiki to learn how to edit this file.") + "\r\n")
|
||||
f.write("\#-------------------------------\r\n")
|
||||
GameData::Species.each do |species_data|
|
||||
moveset = shadow_movesets[species_data.id]
|
||||
next if !moveset || moveset.length == 0
|
||||
f.write(sprintf("%s = %s\r\n", species_data.id, moveset.join(",")))
|
||||
end
|
||||
}
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Save Regional Dexes data to PBS file
|
||||
#===============================================================================
|
||||
def pbSaveRegionalDexes
|
||||
dex_lists = pbLoadRegionalDexes
|
||||
File.open("PBS/regionaldexes.txt", "wb") { |f|
|
||||
f.write(0xEF.chr)
|
||||
f.write(0xBB.chr)
|
||||
f.write(0xBF.chr)
|
||||
f.write("\# " + _INTL("See the documentation on the wiki to learn how to edit this file.") + "\r\n")
|
||||
# Write each Dex list in turn
|
||||
dex_lists.each_with_index do |list, index|
|
||||
f.write("\#-------------------------------\r\n")
|
||||
f.write("[#{index}]")
|
||||
comma = false
|
||||
current_family = nil
|
||||
list.each do |species|
|
||||
next if !species
|
||||
if current_family && current_family.include?(species)
|
||||
f.write(",") if comma
|
||||
else
|
||||
current_family = EvolutionHelper.all_related_species(species)
|
||||
comma = false
|
||||
f.write("\r\n")
|
||||
end
|
||||
f.write(species)
|
||||
comma = true
|
||||
end
|
||||
f.write("\r\n")
|
||||
end
|
||||
}
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Save Battle Tower trainer data to PBS file
|
||||
#===============================================================================
|
||||
def pbSaveBTTrainers(bttrainers,filename)
|
||||
return if !bttrainers || !filename
|
||||
btTrainersRequiredTypes = {
|
||||
"Type" => [0,"e",nil], # Specifies a trainer
|
||||
"Name" => [1,"s"],
|
||||
"BeginSpeech" => [2,"s"],
|
||||
"EndSpeechWin" => [3,"s"],
|
||||
"EndSpeechLose" => [4,"s"],
|
||||
"PokemonNos" => [5,"*u"]
|
||||
}
|
||||
File.open(filename,"wb") { |f|
|
||||
f.write(0xEF.chr)
|
||||
f.write(0xBB.chr)
|
||||
f.write(0xBF.chr)
|
||||
f.write("\# " + _INTL("See the documentation on the wiki to learn how to edit this file.") + "\r\n")
|
||||
for i in 0...bttrainers.length
|
||||
next if !bttrainers[i]
|
||||
f.write("\#-------------------------------\r\n")
|
||||
f.write(sprintf("[%03d]\r\n",i))
|
||||
for key in btTrainersRequiredTypes.keys
|
||||
schema = btTrainersRequiredTypes[key]
|
||||
record = bttrainers[i][schema[0]]
|
||||
next if record==nil
|
||||
f.write(sprintf("%s = ",key))
|
||||
if key=="Type"
|
||||
f.write(record.to_s)
|
||||
elsif key=="PokemonNos"
|
||||
f.write(record.join(",")) # pbWriteCsvRecord somehow won't work here
|
||||
else
|
||||
pbWriteCsvRecord(record,f,schema)
|
||||
end
|
||||
f.write(sprintf("\r\n"))
|
||||
end
|
||||
end
|
||||
}
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Save Battle Tower Pokémon data to PBS file
|
||||
#===============================================================================
|
||||
def pbSaveBattlePokemon(btpokemon,filename)
|
||||
return if !btpokemon || !filename
|
||||
species = {0=>""}
|
||||
moves = {0=>""}
|
||||
items = {0=>""}
|
||||
natures = {}
|
||||
File.open(filename,"wb") { |f|
|
||||
f.write(0xEF.chr)
|
||||
f.write(0xBB.chr)
|
||||
f.write(0xBF.chr)
|
||||
f.write("\# " + _INTL("See the documentation on the wiki to learn how to edit this file.") + "\r\n")
|
||||
f.write("\#-------------------------------\r\n")
|
||||
for i in 0...btpokemon.length
|
||||
Graphics.update if i%500==0
|
||||
pkmn = btpokemon[i]
|
||||
f.write(pbFastInspect(pkmn,moves,species,items,natures))
|
||||
f.write("\r\n")
|
||||
end
|
||||
}
|
||||
end
|
||||
|
||||
def pbFastInspect(pkmn,moves,species,items,natures)
|
||||
c1 = (species[pkmn.species]) ? species[pkmn.species] : (species[pkmn.species] = GameData::Species.get(pkmn.species).species.to_s)
|
||||
c2 = (items[pkmn.item]) ? items[pkmn.item] : (items[pkmn.item] = GameData::Item.get(pkmn.item).id.to_s)
|
||||
c3 = (natures[pkmn.nature]) ? natures[pkmn.nature] :
|
||||
(natures[pkmn.nature] = getConstantName(PBNatures,pkmn.nature))
|
||||
evlist = ""
|
||||
ev = pkmn.ev
|
||||
evs = ["HP","ATK","DEF","SPD","SA","SD"]
|
||||
for i in 0...ev
|
||||
if ((ev&(1<<i))!=0)
|
||||
evlist += "," if evlist.length>0
|
||||
evlist += evs[i]
|
||||
end
|
||||
end
|
||||
c4 = (moves[pkmn.move1]) ? moves[pkmn.move1] : (moves[pkmn.move1] = GameData::Move.get(pkmn.move1).id.to_s)
|
||||
c5 = (moves[pkmn.move2]) ? moves[pkmn.move2] : (moves[pkmn.move2] = GameData::Move.get(pkmn.move2).id.to_s)
|
||||
c6 = (moves[pkmn.move3]) ? moves[pkmn.move3] : (moves[pkmn.move3] = GameData::Move.get(pkmn.move3).id.to_s)
|
||||
c7 = (moves[pkmn.move4]) ? moves[pkmn.move4] : (moves[pkmn.move4] = GameData::Move.get(pkmn.move4).id.to_s)
|
||||
return "#{c1};#{c2};#{c3};#{evlist};#{c4},#{c5},#{c6},#{c7}"
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Save all data to PBS files
|
||||
#===============================================================================
|
||||
def pbSaveAllData
|
||||
pbSaveTypes; Graphics.update
|
||||
pbSaveAbilities; Graphics.update
|
||||
pbSaveMoveData; Graphics.update
|
||||
pbSaveConnectionData; Graphics.update
|
||||
pbSaveMetadata; Graphics.update
|
||||
pbSaveItems; Graphics.update
|
||||
pbSaveBerryPlants; Graphics.update
|
||||
pbSaveTrainerLists; Graphics.update
|
||||
pbSaveEncounterData; Graphics.update
|
||||
pbSaveTrainerTypes; Graphics.update
|
||||
pbSaveTrainerBattles; Graphics.update
|
||||
pbSaveTownMap; Graphics.update
|
||||
pbSavePhoneData; Graphics.update
|
||||
pbSavePokemonData; Graphics.update
|
||||
pbSavePokemonFormsData; Graphics.update
|
||||
pbSaveShadowMoves; Graphics.update
|
||||
pbSaveRegionalDexes; Graphics.update
|
||||
end
|
||||
@@ -1,116 +0,0 @@
|
||||
#===============================================================================
|
||||
# String formatting, conversion of value to string
|
||||
#===============================================================================
|
||||
def csvQuote(str,always=false)
|
||||
return "" if !str || str==""
|
||||
if always || str[/[,\"]/] # || str[/^\s/] || str[/\s$/] || str[/^#/]
|
||||
str = str.gsub(/[\"]/,"\\\"")
|
||||
str = "\"#{str}\""
|
||||
end
|
||||
return str
|
||||
end
|
||||
|
||||
def csvQuoteAlways(str)
|
||||
return csvQuote(str,true)
|
||||
end
|
||||
|
||||
def pbWriteCsvRecord(record,file,schema)
|
||||
rec = (record.is_a?(Array)) ? record.clone : [record]
|
||||
for i in 0...schema[1].length
|
||||
chr = schema[1][i,1]
|
||||
file.write(",") if i>0
|
||||
if rec[i].nil?
|
||||
# do nothing
|
||||
elsif rec[i].is_a?(String)
|
||||
file.write(csvQuote(rec[i]))
|
||||
elsif rec[i].is_a?(Symbol)
|
||||
file.write(csvQuote(rec[i].to_s))
|
||||
elsif rec[i]==true
|
||||
file.write("true")
|
||||
elsif rec[i]==false
|
||||
file.write("false")
|
||||
elsif rec[i].is_a?(Numeric)
|
||||
case chr
|
||||
when "e", "E" # Enumerable
|
||||
enumer = schema[2+i]
|
||||
if enumer.is_a?(Array)
|
||||
file.write(enumer[rec[i]])
|
||||
elsif enumer.is_a?(Symbol) || enumer.is_a?(String)
|
||||
mod = Object.const_get(enumer.to_sym)
|
||||
file.write(getConstantName(mod,rec[i]))
|
||||
elsif enumer.is_a?(Module)
|
||||
file.write(getConstantName(enumer,rec[i]))
|
||||
elsif enumer.is_a?(Hash)
|
||||
for key in enumer.keys
|
||||
if enumer[key]==rec[i]
|
||||
file.write(key)
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
when "y", "Y" # Enumerable or integer
|
||||
enumer = schema[2+i]
|
||||
if enumer.is_a?(Array)
|
||||
if enumer[rec[i]]!=nil
|
||||
file.write(enumer[rec[i]])
|
||||
else
|
||||
file.write(rec[i])
|
||||
end
|
||||
elsif enumer.is_a?(Symbol) || enumer.is_a?(String)
|
||||
mod = Object.const_get(enumer.to_sym)
|
||||
file.write(getConstantNameOrValue(mod,rec[i]))
|
||||
elsif enumer.is_a?(Module)
|
||||
file.write(getConstantNameOrValue(enumer,rec[i]))
|
||||
elsif enumer.is_a?(Hash)
|
||||
hasenum = false
|
||||
for key in enumer.keys
|
||||
if enumer[key]==rec[i]
|
||||
file.write(key)
|
||||
hasenum = true; break
|
||||
end
|
||||
end
|
||||
file.write(rec[i]) unless hasenum
|
||||
end
|
||||
else # Any other record type
|
||||
file.write(rec[i].inspect)
|
||||
end
|
||||
else
|
||||
file.write(rec[i].inspect)
|
||||
end
|
||||
end
|
||||
return record
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Enum const manipulators and parsers
|
||||
#===============================================================================
|
||||
def getConstantName(mod,value)
|
||||
mod = Object.const_get(mod) if mod.is_a?(Symbol)
|
||||
for c in mod.constants
|
||||
return c if mod.const_get(c.to_sym)==value
|
||||
end
|
||||
raise _INTL("Value {1} not defined by a constant in {2}",value,mod.name)
|
||||
end
|
||||
|
||||
def getConstantNameOrValue(mod,value)
|
||||
mod = Object.const_get(mod) if mod.is_a?(Symbol)
|
||||
for c in mod.constants
|
||||
return c if mod.const_get(c.to_sym)==value
|
||||
end
|
||||
return value.inspect
|
||||
end
|
||||
|
||||
def setConstantName(mod,value,name)
|
||||
mod = Object.const_get(mod) if mod.is_a?(Symbol)
|
||||
for c in mod.constants
|
||||
mod.send(:remove_const,c.to_sym) if mod.const_get(c.to_sym)==value
|
||||
end
|
||||
mod.const_set(name,value)
|
||||
end
|
||||
|
||||
def removeConstantValue(mod,value)
|
||||
mod = Object.const_get(mod) if mod.is_a?(Symbol)
|
||||
for c in mod.constants
|
||||
mod.send(:remove_const,c.to_sym) if mod.const_get(c.to_sym)==value
|
||||
end
|
||||
end
|
||||
@@ -108,110 +108,6 @@ def pbMapTree
|
||||
return retarray
|
||||
end
|
||||
|
||||
|
||||
|
||||
#===============================================================================
|
||||
# Make up internal names for things based on their actual names
|
||||
#===============================================================================
|
||||
module MakeshiftConsts
|
||||
@@consts = []
|
||||
|
||||
def self.get(c,i,modname=nil)
|
||||
@@consts[c] = [] if !@@consts[c]
|
||||
return @@consts[c][i] if @@consts[c][i]
|
||||
if modname
|
||||
v = getConstantName(modname,i) rescue nil
|
||||
if v
|
||||
@@consts[c][i] = v
|
||||
return v
|
||||
end
|
||||
end
|
||||
trname = pbGetMessage(c,i)
|
||||
trconst = trname.gsub(/é/,"e")
|
||||
trconst = trconst.upcase
|
||||
trconst = trconst.gsub(/♀/,"fE")
|
||||
trconst = trconst.gsub(/♂/,"mA")
|
||||
trconst = trconst.gsub(/[^A-Za-z0-9_]/,"")
|
||||
if trconst.length==0
|
||||
return nil if trname.length==0
|
||||
trconst = sprintf("T_%03d",i)
|
||||
elsif !trconst[0,1][/[A-Z]/]
|
||||
trconst = "T_"+trconst
|
||||
end
|
||||
while @@consts[c].include?(trconst)
|
||||
trconst = sprintf("%s_%03d",trconst,i)
|
||||
end
|
||||
@@consts[c][i] = trconst
|
||||
return trconst
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
def pbGetEvolutionConst(i)
|
||||
ret = MakeshiftConsts.get(50,i,PBEvolution)
|
||||
if !ret
|
||||
ret = ["None",
|
||||
"Happiness","HappinessDay","HappinessNight","Level","Trade",
|
||||
"TradeItem","Item","AttackGreater","AtkDefEqual","DefenseGreater",
|
||||
"Silcoon","Cascoon","Ninjask","Shedinja","Beauty",
|
||||
"ItemMale","ItemFemale","DayHoldItem","NightHoldItem","HasMove",
|
||||
"HasInParty","LevelMale","LevelFemale","Location","TradeSpecies",
|
||||
"Custom1","Custom2","Custom3","Custom4","Custom5"]
|
||||
i = 0 if i>=ret.length || i<0
|
||||
ret = ret[i]
|
||||
end
|
||||
return ret
|
||||
end
|
||||
|
||||
def pbGetEggGroupConst(i)
|
||||
ret = MakeshiftConsts.get(51,i,PBEggGroups)
|
||||
if !ret
|
||||
ret = ["Undiscovered",
|
||||
"Monster","Water1","Bug","Flying","Field",
|
||||
"Fairy","Grass","Humanlike","Water3","Mineral",
|
||||
"Amorphous","Water2","Ditto","Dragon"][i]
|
||||
i = 0 if i>=ret.length || i<0
|
||||
ret = ret[i]
|
||||
end
|
||||
return ret
|
||||
end
|
||||
|
||||
def pbGetColorConst(i)
|
||||
ret = MakeshiftConsts.get(52,i,PBColors)
|
||||
if !ret
|
||||
ret = ["Red","Blue","Yellow","Green","Black","Brown","Purple","Gray","White","Pink"]
|
||||
i = 0 if i>=ret.length || i<0
|
||||
ret = ret[i]
|
||||
end
|
||||
return ret
|
||||
end
|
||||
|
||||
def pbGetGenderConst(i)
|
||||
ret = MakeshiftConsts.get(53,i,PBGenderRates)
|
||||
if !ret
|
||||
ret = ["Genderless","AlwaysMale","FemaleOneEighth","Female25Percent",
|
||||
"Female50Percent","Female75Percent","FemaleSevenEighths",
|
||||
"AlwaysFemale"]
|
||||
i = 0 if i>=ret.length || i<0
|
||||
ret = ret[i]
|
||||
end
|
||||
return ret
|
||||
end
|
||||
|
||||
def pbGetHabitatConst(i)
|
||||
ret = MakeshiftConsts.get(54,i,PBHabitats)
|
||||
if !ret
|
||||
ret = ["","Grassland","Forest","WatersEdge","Sea","Cave","Mountain",
|
||||
"RoughTerrain","Urban","Rare"]
|
||||
i = 0 if i>=ret.length || i<0
|
||||
ret = ret[i]
|
||||
end
|
||||
return ret
|
||||
end
|
||||
|
||||
|
||||
|
||||
#===============================================================================
|
||||
# List all members of a class
|
||||
#===============================================================================
|
||||
|
||||
@@ -284,7 +284,8 @@ class MapScreenScene
|
||||
|
||||
def serializeConnectionData
|
||||
conndata=generateConnectionData()
|
||||
pbSerializeConnectionData(conndata,@mapinfos)
|
||||
save_data(conndata, "Data/map_connections.dat")
|
||||
Compiler.write_connections
|
||||
@mapconns=conndata
|
||||
end
|
||||
|
||||
@@ -575,7 +576,7 @@ class MapScreenScene
|
||||
MapFactoryHelper.clear
|
||||
save_data(@encdata,"Data/encounters.dat")
|
||||
$PokemonTemp.encountersData = nil
|
||||
pbSaveEncounterData
|
||||
Compiler.write_encounters
|
||||
end
|
||||
break if pbConfirmMessage(_INTL("Exit from the editor?"))
|
||||
end
|
||||
@@ -32,8 +32,8 @@ def pbAutoPositionAll
|
||||
bitmap2.dispose if bitmap2
|
||||
end
|
||||
GameData::Species.save
|
||||
pbSavePokemonData
|
||||
pbSavePokemonFormsData
|
||||
Compiler.write_pokemon
|
||||
Compiler.write_pokemon_forms
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
@@ -97,8 +97,8 @@ class SpritePositioner
|
||||
|
||||
def pbSaveMetrics
|
||||
GameData::Species.save
|
||||
pbSavePokemonData
|
||||
pbSavePokemonFormsData
|
||||
Compiler.write_pokemon
|
||||
Compiler.write_pokemon_forms
|
||||
end
|
||||
|
||||
def update
|
||||
File diff suppressed because it is too large
Load Diff
@@ -76,6 +76,19 @@ module Compiler
|
||||
return line
|
||||
end
|
||||
|
||||
def csvQuote(str,always=false)
|
||||
return "" if !str || str==""
|
||||
if always || str[/[,\"]/] # || str[/^\s/] || str[/\s$/] || str[/^#/]
|
||||
str = str.gsub(/[\"]/,"\\\"")
|
||||
str = "\"#{str}\""
|
||||
end
|
||||
return str
|
||||
end
|
||||
|
||||
def csvQuoteAlways(str)
|
||||
return csvQuote(str,true)
|
||||
end
|
||||
|
||||
#=============================================================================
|
||||
# PBS file readers
|
||||
#=============================================================================
|
||||
@@ -115,7 +128,7 @@ module Compiler
|
||||
yield lastsection,sectionname if havesection
|
||||
end
|
||||
|
||||
# Used for pokemon.txt
|
||||
# Used for types.txt, pokemon.txt, metadata.txt
|
||||
def pbEachFileSection(f)
|
||||
pbEachFileSectionEx(f) { |section,name|
|
||||
yield section,name.to_i if block_given? && name[/^\d+$/]
|
||||
@@ -201,7 +214,7 @@ module Compiler
|
||||
}
|
||||
end
|
||||
|
||||
# Used for connections.txt, abilities.txt, moves.txt, trainertypes.txt
|
||||
# Used for connections.txt, abilities.txt, moves.txt, regionaldexes.txt
|
||||
def pbCompilerEachPreppedLine(filename)
|
||||
File.open(filename,"rb") { |f|
|
||||
FileLineData.file = filename
|
||||
@@ -514,34 +527,73 @@ module Compiler
|
||||
end
|
||||
|
||||
#=============================================================================
|
||||
# Check whether a number fits in a given numerical range (all unused)
|
||||
# Write values to a file using a schema
|
||||
#=============================================================================
|
||||
def pbCheckByte(x,valuename)
|
||||
if x<0 || x>255
|
||||
raise _INTL("The value \"{1}\" must be from 0 through 255 (00-FF in hex), got a value of {2}\r\n{3}",
|
||||
valuename,x,FileLineData.linereport)
|
||||
def pbWriteCsvRecord(record,file,schema)
|
||||
rec = (record.is_a?(Array)) ? record.clone : [record]
|
||||
for i in 0...schema[1].length
|
||||
chr = schema[1][i,1]
|
||||
file.write(",") if i>0
|
||||
if rec[i].nil?
|
||||
# do nothing
|
||||
elsif rec[i].is_a?(String)
|
||||
file.write(csvQuote(rec[i]))
|
||||
elsif rec[i].is_a?(Symbol)
|
||||
file.write(csvQuote(rec[i].to_s))
|
||||
elsif rec[i]==true
|
||||
file.write("true")
|
||||
elsif rec[i]==false
|
||||
file.write("false")
|
||||
elsif rec[i].is_a?(Numeric)
|
||||
case chr
|
||||
when "e", "E" # Enumerable
|
||||
enumer = schema[2+i]
|
||||
if enumer.is_a?(Array)
|
||||
file.write(enumer[rec[i]])
|
||||
elsif enumer.is_a?(Symbol) || enumer.is_a?(String)
|
||||
mod = Object.const_get(enumer.to_sym)
|
||||
file.write(getConstantName(mod,rec[i]))
|
||||
elsif enumer.is_a?(Module)
|
||||
file.write(getConstantName(enumer,rec[i]))
|
||||
elsif enumer.is_a?(Hash)
|
||||
for key in enumer.keys
|
||||
if enumer[key]==rec[i]
|
||||
file.write(key)
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
def pbCheckSignedByte(x,valuename)
|
||||
if x<-128 || x>127
|
||||
raise _INTL("The value \"{1}\" must be from -128 through 127, got a value of {2}\r\n{3}",
|
||||
valuename,x,FileLineData.linereport)
|
||||
end
|
||||
when "y", "Y" # Enumerable or integer
|
||||
enumer = schema[2+i]
|
||||
if enumer.is_a?(Array)
|
||||
if enumer[rec[i]]!=nil
|
||||
file.write(enumer[rec[i]])
|
||||
else
|
||||
file.write(rec[i])
|
||||
end
|
||||
elsif enumer.is_a?(Symbol) || enumer.is_a?(String)
|
||||
mod = Object.const_get(enumer.to_sym)
|
||||
file.write(getConstantNameOrValue(mod,rec[i]))
|
||||
elsif enumer.is_a?(Module)
|
||||
file.write(getConstantNameOrValue(enumer,rec[i]))
|
||||
elsif enumer.is_a?(Hash)
|
||||
hasenum = false
|
||||
for key in enumer.keys
|
||||
if enumer[key]==rec[i]
|
||||
file.write(key)
|
||||
hasenum = true; break
|
||||
end
|
||||
end
|
||||
|
||||
def pbCheckWord(x,valuename)
|
||||
if x<0 || x>65535
|
||||
raise _INTL("The value \"{1}\" must be from 0 through 65535 (0000-FFFF in hex), got a value of {2}\r\n{3}",
|
||||
valuename,x,FileLineData.linereport)
|
||||
file.write(rec[i]) unless hasenum
|
||||
end
|
||||
else # Any other record type
|
||||
file.write(rec[i].inspect)
|
||||
end
|
||||
else
|
||||
file.write(rec[i].inspect)
|
||||
end
|
||||
end
|
||||
|
||||
def pbCheckSignedWord(x,valuename)
|
||||
if x<-32768 || x>32767
|
||||
raise _INTL("The value \"{1}\" must be from -32768 through 32767, got a value of {2}\r\n{3}",
|
||||
valuename,x,FileLineData.linereport)
|
||||
end
|
||||
return record
|
||||
end
|
||||
|
||||
#=============================================================================
|
||||
@@ -625,12 +677,14 @@ module Compiler
|
||||
MessageTypes.loadMessageFile("Data/messages.dat")
|
||||
end
|
||||
if mustCompile
|
||||
yield(_INTL("Compiling type data"))
|
||||
compile_types # No dependencies
|
||||
yield(_INTL("Compiling town map data"))
|
||||
compile_town_map # No dependencies
|
||||
yield(_INTL("Compiling map connection data"))
|
||||
compile_connections # No dependencies
|
||||
yield(_INTL("Compiling phone data"))
|
||||
compile_phone
|
||||
yield(_INTL("Compiling type data"))
|
||||
compile_types # No dependencies
|
||||
yield(_INTL("Compiling ability data"))
|
||||
compile_abilities # No dependencies
|
||||
yield(_INTL("Compiling move data"))
|
||||
@@ -645,22 +699,20 @@ module Compiler
|
||||
compile_pokemon_forms # Depends on Species, Move, Item, Type, Ability
|
||||
yield(_INTL("Compiling machine data"))
|
||||
compile_move_compatibilities # Depends on Species, Move
|
||||
yield(_INTL("Compiling Trainer type data"))
|
||||
compile_trainer_types # No dependencies
|
||||
yield(_INTL("Compiling Trainer data"))
|
||||
compile_trainers # Depends on Species, Item, Move
|
||||
yield(_INTL("Compiling phone data"))
|
||||
compile_phone
|
||||
yield(_INTL("Compiling metadata"))
|
||||
compile_metadata # Depends on TrainerType
|
||||
yield(_INTL("Compiling battle Trainer data"))
|
||||
compile_trainer_lists # Depends on TrainerType
|
||||
yield(_INTL("Compiling encounter data"))
|
||||
compile_encounters # Depends on Species
|
||||
yield(_INTL("Compiling shadow moveset data"))
|
||||
compile_shadow_movesets # Depends on Species, Move
|
||||
yield(_INTL("Compiling Regional Dexes"))
|
||||
compile_regional_dexes # Depends on Species
|
||||
yield(_INTL("Compiling encounter data"))
|
||||
compile_encounters # Depends on Species
|
||||
yield(_INTL("Compiling Trainer type data"))
|
||||
compile_trainer_types # No dependencies
|
||||
yield(_INTL("Compiling Trainer data"))
|
||||
compile_trainers # Depends on Species, Item, Move
|
||||
yield(_INTL("Compiling battle Trainer data"))
|
||||
compile_trainer_lists # Depends on TrainerType
|
||||
yield(_INTL("Compiling metadata"))
|
||||
compile_metadata # Depends on TrainerType
|
||||
yield(_INTL("Compiling animations"))
|
||||
compile_animations
|
||||
yield(_INTL("Converting events"))
|
||||
@@ -698,8 +750,7 @@ module Compiler
|
||||
"trainer_lists.dat",
|
||||
"trainer_types.dat",
|
||||
"trainers.dat",
|
||||
"types.dat",
|
||||
"Constants.rxdata"
|
||||
"types.dat"
|
||||
]
|
||||
textFiles = [
|
||||
"abilities.txt",
|
||||
@@ -728,7 +779,7 @@ module Compiler
|
||||
# If no PBS file, create one and fill it, then recompile
|
||||
if !safeIsDirectory?("PBS")
|
||||
Dir.mkdir("PBS") rescue nil
|
||||
pbSaveAllData
|
||||
write_all
|
||||
mustCompile = true
|
||||
end
|
||||
# Should recompile if holding Ctrl
|
||||
@@ -1,305 +0,0 @@
|
||||
# NOTE: Everything in here is unused.
|
||||
#===============================================================================
|
||||
# Serial record
|
||||
#===============================================================================
|
||||
# Unused
|
||||
module SerialRecords
|
||||
class SerialRecord < Array
|
||||
def bytesize
|
||||
return SerialRecord.bytesize(self)
|
||||
end
|
||||
|
||||
def encode(strm)
|
||||
return SerialRecord.encode(self,strm)
|
||||
end
|
||||
|
||||
def self.bytesize(arr)
|
||||
ret = 0
|
||||
return 0 if !arr
|
||||
for field in arr
|
||||
if field==nil || field==true || field==false
|
||||
ret += 1
|
||||
elsif field.is_a?(String)
|
||||
ret += strSize(field)+1
|
||||
elsif field.is_a?(Numeric)
|
||||
ret += intSize(field)+1
|
||||
end
|
||||
end
|
||||
return ret
|
||||
end
|
||||
|
||||
def self.encode(arr,strm)
|
||||
return if !arr
|
||||
for field in arr
|
||||
if field==nil
|
||||
strm.write("0")
|
||||
elsif field==true
|
||||
strm.write("T")
|
||||
elsif field==false
|
||||
strm.write("F")
|
||||
elsif field.is_a?(String)
|
||||
strm.write("\"")
|
||||
encodeString(strm,field)
|
||||
elsif field.is_a?(Numeric)
|
||||
strm.write("i")
|
||||
encodeInt(strm,field)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def self.decode(strm,offset,length)
|
||||
ret = SerialRecord.new
|
||||
strm.pos = offset
|
||||
while strm.pos<offset+length
|
||||
datatype = strm.read(1)
|
||||
case datatype
|
||||
when "0" then ret.push(nil)
|
||||
when "T" then ret.push(true)
|
||||
when "F" then ret.push(false)
|
||||
when "\"" then ret.push(decodeString(strm))
|
||||
when "i" then ret.push(decodeInt(strm))
|
||||
end
|
||||
end
|
||||
return ret
|
||||
end
|
||||
end
|
||||
|
||||
def self.readSerialRecords(filename)
|
||||
ret = []
|
||||
return ret if !pbRgssExists?(filename)
|
||||
pbRgssOpen(filename,"rb") { |file|
|
||||
numrec = file.fgetdw>>3
|
||||
curpos = 0
|
||||
numrec.times do
|
||||
file.pos = curpos
|
||||
offset = file.fgetdw
|
||||
length = file.fgetdw
|
||||
record = SerialRecord.decode(file,offset,length)
|
||||
ret.push(record)
|
||||
curpos += 8
|
||||
end
|
||||
}
|
||||
return ret
|
||||
end
|
||||
|
||||
def self.writeSerialRecords(filename,records)
|
||||
File.open(filename,"wb") { |file|
|
||||
totalsize = records.length*8
|
||||
for record in records
|
||||
file.fputdw(totalsize)
|
||||
bytesize = record.bytesize
|
||||
file.fputdw(bytesize)
|
||||
totalsize += bytesize
|
||||
end
|
||||
for record in records
|
||||
record.encode(file)
|
||||
end
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Data structures
|
||||
#===============================================================================
|
||||
# Unused
|
||||
class ByteArray
|
||||
include Enumerable
|
||||
|
||||
def initialize(data=nil)
|
||||
@a = (data) ? data.unpack("C*") : []
|
||||
end
|
||||
|
||||
def [](i); return @a[i]; end
|
||||
def []=(i,value); @a[i] = value; end
|
||||
|
||||
def length; @a.length; end
|
||||
def size; @a.size; end
|
||||
|
||||
def fillNils(length,value)
|
||||
for i in 0...length
|
||||
@a[i] = value if !@a[i]
|
||||
end
|
||||
end
|
||||
|
||||
def each
|
||||
@a.each { |i| yield i}
|
||||
end
|
||||
|
||||
def self._load(str)
|
||||
return self.new(str)
|
||||
end
|
||||
|
||||
def _dump(_depth=100)
|
||||
return @a.pack("C*")
|
||||
end
|
||||
end
|
||||
|
||||
# Unused
|
||||
class WordArray
|
||||
include Enumerable
|
||||
|
||||
def initialize(data=nil)
|
||||
@a = (data) ? data.unpack("v*") : []
|
||||
end
|
||||
|
||||
def [](i); return @a[i]; end
|
||||
def []=(i,value); @a[i] = value; end
|
||||
|
||||
def length; @a.length; end
|
||||
def size; @a.size; end
|
||||
|
||||
def fillNils(length,value)
|
||||
for i in 0...length
|
||||
@a[i] = value if !@a[i]
|
||||
end
|
||||
end
|
||||
|
||||
def each
|
||||
@a.each { |i| yield i}
|
||||
end
|
||||
|
||||
def self._load(str)
|
||||
return self.new(str)
|
||||
end
|
||||
|
||||
def _dump(_depth=100)
|
||||
return @a.pack("v*")
|
||||
end
|
||||
end
|
||||
|
||||
# Unused
|
||||
class SignedWordArray
|
||||
include Enumerable
|
||||
|
||||
def initialize(data=nil)
|
||||
@a = (data) ? data.unpack("v*") : []
|
||||
end
|
||||
|
||||
def []=(i,value)
|
||||
@a[i] = value
|
||||
end
|
||||
|
||||
def [](i)
|
||||
v = @a[i]
|
||||
return 0 if !v
|
||||
return (v<0x8000) ? v : -((~v)&0xFFFF)-1
|
||||
end
|
||||
|
||||
def length; @a.length; end
|
||||
def size; @a.size; end
|
||||
|
||||
def fillNils(length,value)
|
||||
for i in 0...length
|
||||
@a[i] = value if !@a[i]
|
||||
end
|
||||
end
|
||||
|
||||
def each
|
||||
@a.each { |i| yield i}
|
||||
end
|
||||
|
||||
def self._load(str)
|
||||
return self.new(str)
|
||||
end
|
||||
|
||||
def _dump(_depth=100)
|
||||
return @a.pack("v*")
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Encoding and decoding
|
||||
#===============================================================================
|
||||
# Unused
|
||||
def intSize(value)
|
||||
return 1 if value<0x80
|
||||
return 2 if value<0x4000
|
||||
return 3 if value<0x200000
|
||||
return 4 if value<0x10000000
|
||||
return 5
|
||||
end
|
||||
|
||||
# Unused
|
||||
def encodeInt(strm,value)
|
||||
num = 0
|
||||
loop do
|
||||
if value<0x80
|
||||
strm.fputb(value)
|
||||
return num+1
|
||||
end
|
||||
strm.fputb(0x80|(value&0x7F))
|
||||
value >>= 7
|
||||
num += 1
|
||||
end
|
||||
end
|
||||
|
||||
# Unused
|
||||
def decodeInt(strm)
|
||||
bits = 0
|
||||
curbyte = 0
|
||||
ret = 0
|
||||
begin
|
||||
curbyte = strm.fgetb
|
||||
ret += (curbyte&0x7F)<<bits
|
||||
bits += 7
|
||||
end while ((curbyte&0x80)>0)&&bits<0x1d
|
||||
return ret
|
||||
end
|
||||
|
||||
# Unused
|
||||
def strSize(str)
|
||||
return str.length+intSize(str.length)
|
||||
end
|
||||
|
||||
# Unused
|
||||
def encodeString(strm,str)
|
||||
encodeInt(strm,str.length)
|
||||
strm.write(str)
|
||||
end
|
||||
|
||||
# Unused
|
||||
def decodeString(strm)
|
||||
len = decodeInt(strm)
|
||||
return strm.read(len)
|
||||
end
|
||||
|
||||
# Unused
|
||||
def frozenArrayValue(arr)
|
||||
typestring = ""
|
||||
for i in 0...arr.length
|
||||
if i>0
|
||||
typestring += ((i%20)==0) ? ",\r\n" : ","
|
||||
end
|
||||
typestring += arr[i].to_s
|
||||
end
|
||||
return "["+typestring+"].freeze"
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Scripted constants
|
||||
#===============================================================================
|
||||
# Unused
|
||||
def pbFindScript(a,name)
|
||||
a.each { |i|
|
||||
next if !i
|
||||
return i if i[1]==name
|
||||
}
|
||||
return nil
|
||||
end
|
||||
|
||||
# Unused
|
||||
def pbAddScript(script,sectionname)
|
||||
begin
|
||||
scripts = load_data("Data/Constants.rxdata")
|
||||
scripts = [] if !scripts
|
||||
rescue
|
||||
scripts = []
|
||||
end
|
||||
if false # s
|
||||
s = pbFindScript(scripts,sectionname)
|
||||
s[2]+=Zlib::Deflate.deflate("#{script}\r\n")
|
||||
else
|
||||
scripts.push([rand(100000000),sectionname,Zlib::Deflate.deflate("#{script}\r\n")])
|
||||
end
|
||||
save_data(scripts,"Data/Constants.rxdata")
|
||||
end
|
||||
@@ -2,96 +2,7 @@ module Compiler
|
||||
module_function
|
||||
|
||||
#=============================================================================
|
||||
# Compile metadata
|
||||
#=============================================================================
|
||||
def compile_metadata
|
||||
GameData::Metadata::DATA.clear
|
||||
GameData::MapMetadata::DATA.clear
|
||||
# Read from PBS file
|
||||
File.open("PBS/metadata.txt", "rb") { |f|
|
||||
FileLineData.file = "PBS/metadata.txt" # For error reporting
|
||||
# Read a whole section's lines at once, then run through this code.
|
||||
# contents is a hash containing all the XXX=YYY lines in that section, where
|
||||
# the keys are the XXX and the values are the YYY (as unprocessed strings).
|
||||
pbEachFileSection(f) { |contents, map_id|
|
||||
schema = (map_id == 0) ? GameData::Metadata::SCHEMA : GameData::MapMetadata::SCHEMA
|
||||
# Go through schema hash of compilable data and compile this section
|
||||
for key in schema.keys
|
||||
FileLineData.setSection(map_id, key, contents[key]) # For error reporting
|
||||
# Skip empty properties, or raise an error if a required property is
|
||||
# empty
|
||||
if contents[key].nil?
|
||||
if map_id == 0 && ["Home", "PlayerA"].include?(key)
|
||||
raise _INTL("The entry {1} is required in PBS/metadata.txt section 0.", key)
|
||||
end
|
||||
next
|
||||
end
|
||||
# Compile value for key
|
||||
value = pbGetCsvRecord(contents[key], key, schema[key])
|
||||
value = nil if value.is_a?(Array) && value.length == 0
|
||||
contents[key] = value
|
||||
end
|
||||
if map_id == 0 # Global metadata
|
||||
# Construct metadata hash
|
||||
metadata_hash = {
|
||||
:id => map_id,
|
||||
:home => contents["Home"],
|
||||
:wild_battle_BGM => contents["WildBattleBGM"],
|
||||
:trainer_battle_BGM => contents["TrainerBattleBGM"],
|
||||
:wild_victory_ME => contents["WildVictoryME"],
|
||||
:trainer_victory_ME => contents["TrainerVictoryME"],
|
||||
:wild_capture_ME => contents["WildCaptureME"],
|
||||
:surf_BGM => contents["SurfBGM"],
|
||||
:bicycle_BGM => contents["BicycleBGM"],
|
||||
:player_A => contents["PlayerA"],
|
||||
:player_B => contents["PlayerB"],
|
||||
:player_C => contents["PlayerC"],
|
||||
:player_D => contents["PlayerD"],
|
||||
:player_E => contents["PlayerE"],
|
||||
:player_F => contents["PlayerF"],
|
||||
:player_G => contents["PlayerG"],
|
||||
:player_H => contents["PlayerH"]
|
||||
}
|
||||
# Add metadata's data to records
|
||||
GameData::Metadata::DATA[map_id] = GameData::Metadata.new(metadata_hash)
|
||||
else # Map metadata
|
||||
# Construct metadata hash
|
||||
metadata_hash = {
|
||||
:id => map_id,
|
||||
:outdoor_map => contents["Outdoor"],
|
||||
:announce_location => contents["ShowArea"],
|
||||
:can_bicycle => contents["Bicycle"],
|
||||
:always_bicycle => contents["BicycleAlways"],
|
||||
:teleport_destination => contents["HealingSpot"],
|
||||
:weather => contents["Weather"],
|
||||
:town_map_position => contents["MapPosition"],
|
||||
:dive_map_id => contents["DiveMap"],
|
||||
:dark_map => contents["DarkMap"],
|
||||
:safari_map => contents["SafariMap"],
|
||||
:snap_edges => contents["SnapEdges"],
|
||||
:random_dungeon => contents["Dungeon"],
|
||||
:battle_background => contents["BattleBack"],
|
||||
:wild_battle_BGM => contents["WildBattleBGM"],
|
||||
:trainer_battle_BGM => contents["TrainerBattleBGM"],
|
||||
:wild_victory_ME => contents["WildVictoryME"],
|
||||
:trainer_victory_ME => contents["TrainerVictoryME"],
|
||||
:wild_capture_ME => contents["WildCaptureME"],
|
||||
:town_map_size => contents["MapSize"],
|
||||
:battle_environment => contents["Environment"]
|
||||
}
|
||||
# Add metadata's data to records
|
||||
GameData::MapMetadata::DATA[map_id] = GameData::MapMetadata.new(metadata_hash)
|
||||
end
|
||||
}
|
||||
}
|
||||
# Save all data
|
||||
GameData::Metadata.save
|
||||
GameData::MapMetadata.save
|
||||
Graphics.update
|
||||
end
|
||||
|
||||
#=============================================================================
|
||||
# Compile town map points
|
||||
# Compile Town Map data
|
||||
#=============================================================================
|
||||
def compile_town_map
|
||||
nonglobaltypes = {
|
||||
@@ -182,36 +93,6 @@ module Compiler
|
||||
Graphics.update
|
||||
end
|
||||
|
||||
#=============================================================================
|
||||
# Compile berry plants
|
||||
#=============================================================================
|
||||
def compile_berry_plants
|
||||
GameData::BerryPlant::DATA.clear
|
||||
pbCompilerEachCommentedLine("PBS/berryplants.txt") { |line, line_no|
|
||||
if line[/^\s*(\w+)\s*=\s*(.*)$/] # Of the format XXX = YYY
|
||||
key = $1
|
||||
value = $2
|
||||
item_symbol = parseItem(key)
|
||||
item_number = GameData::Item.get(item_symbol).id_number
|
||||
line = pbGetCsvRecord(value, line_no, [0, "vuuv"])
|
||||
# Construct berry plant hash
|
||||
berry_plant_hash = {
|
||||
:id => item_symbol,
|
||||
:id_number => item_number,
|
||||
:hours_per_stage => line[0],
|
||||
:drying_per_hour => line[1],
|
||||
:minimum_yield => line[2],
|
||||
:maximum_yield => line[3]
|
||||
}
|
||||
# Add berry plant's data to records
|
||||
GameData::BerryPlant::DATA[item_number] = GameData::BerryPlant::DATA[item_symbol] = GameData::BerryPlant.new(berry_plant_hash)
|
||||
end
|
||||
}
|
||||
# Save all data
|
||||
GameData::BerryPlant.save
|
||||
Graphics.update
|
||||
end
|
||||
|
||||
#=============================================================================
|
||||
# Compile phone messages
|
||||
#=============================================================================
|
||||
@@ -251,7 +132,7 @@ module Compiler
|
||||
end
|
||||
|
||||
#=============================================================================
|
||||
# Compile types
|
||||
# Compile type data
|
||||
#=============================================================================
|
||||
def compile_types
|
||||
GameData::Type::DATA.clear
|
||||
@@ -325,7 +206,7 @@ module Compiler
|
||||
end
|
||||
|
||||
#=============================================================================
|
||||
# Compile abilities
|
||||
# Compile ability data
|
||||
#=============================================================================
|
||||
def compile_abilities
|
||||
GameData::Ability::DATA.clear
|
||||
@@ -359,100 +240,6 @@ module Compiler
|
||||
Graphics.update
|
||||
end
|
||||
|
||||
#=============================================================================
|
||||
# Compile items
|
||||
#=============================================================================
|
||||
=begin
|
||||
class ItemList
|
||||
include Enumerable
|
||||
|
||||
def initialize; @list = []; end
|
||||
def length; @list.length; end
|
||||
def []=(x,v); @list[x] = v; end
|
||||
|
||||
def [](x)
|
||||
if !@list[x]
|
||||
defrecord = SerialRecords::SerialRecord.new
|
||||
defrecord.push(0)
|
||||
defrecord.push("????????")
|
||||
defrecord.push(0)
|
||||
defrecord.push(0)
|
||||
defrecord.push("????????")
|
||||
@list[x] = defrecord
|
||||
return defrecord
|
||||
end
|
||||
return @list[x]
|
||||
end
|
||||
|
||||
def each
|
||||
for i in 0...self.length
|
||||
yield self[i]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def readItemList(filename)
|
||||
ret = ItemList.new
|
||||
return ret if !pbRgssExists?(filename)
|
||||
pbRgssOpen(filename,"rb") { |file|
|
||||
numrec = file.fgetdw>>3
|
||||
curpos = 0
|
||||
numrec.times do
|
||||
file.pos = curpos
|
||||
offset = file.fgetdw
|
||||
length = file.fgetdw
|
||||
record = SerialRecords::SerialRecord.decode(file,offset,length)
|
||||
ret[record[0]] = record
|
||||
curpos += 8
|
||||
end
|
||||
}
|
||||
return ret
|
||||
end
|
||||
=end
|
||||
|
||||
def compile_items
|
||||
GameData::Item::DATA.clear
|
||||
item_names = []
|
||||
item_names_plural = []
|
||||
item_descriptions = []
|
||||
# Read each line of items.txt at a time and compile it into an item
|
||||
pbCompilerEachCommentedLine("PBS/items.txt") { |line, line_no|
|
||||
line = pbGetCsvRecord(line, line_no, [0, "vnssuusuuUN"])
|
||||
item_number = line[0]
|
||||
item_symbol = line[1].to_sym
|
||||
if GameData::Item::DATA[item_number]
|
||||
raise _INTL("Item ID number '{1}' is used twice.\r\n{2}", item_number, FileLineData.linereport)
|
||||
elsif GameData::Item::DATA[item_symbol]
|
||||
raise _INTL("Item ID '{1}' is used twice.\r\n{2}", item_symbol, FileLineData.linereport)
|
||||
end
|
||||
# Construct item hash
|
||||
item_hash = {
|
||||
:id_number => item_number,
|
||||
:id => item_symbol,
|
||||
:name => line[2],
|
||||
:name_plural => line[3],
|
||||
:pocket => line[4],
|
||||
:price => line[5],
|
||||
:description => line[6],
|
||||
:field_use => line[7],
|
||||
:battle_use => line[8],
|
||||
:type => line[9]
|
||||
}
|
||||
item_hash[:move] = parseMove(line[10]) if !nil_or_empty?(line[10])
|
||||
# Add item's data to records
|
||||
GameData::Item::DATA[item_number] = GameData::Item::DATA[item_symbol] = GameData::Item.new(item_hash)
|
||||
item_names[item_number] = item_hash[:name]
|
||||
item_names_plural[item_number] = item_hash[:name_plural]
|
||||
item_descriptions[item_number] = item_hash[:description]
|
||||
}
|
||||
# Save all data
|
||||
GameData::Item.save
|
||||
MessageTypes.setMessages(MessageTypes::Items, item_names)
|
||||
MessageTypes.setMessages(MessageTypes::ItemPlurals, item_names_plural)
|
||||
MessageTypes.setMessages(MessageTypes::ItemDescriptions, item_descriptions)
|
||||
Graphics.update
|
||||
end
|
||||
|
||||
#=============================================================================
|
||||
# Compile move data
|
||||
#=============================================================================
|
||||
@@ -510,49 +297,83 @@ module Compiler
|
||||
end
|
||||
|
||||
#=============================================================================
|
||||
# Compile battle animations
|
||||
# Compile item data
|
||||
#=============================================================================
|
||||
def compile_animations
|
||||
begin
|
||||
pbanims = load_data("Data/PkmnAnimations.rxdata")
|
||||
rescue
|
||||
pbanims = PBAnimations.new
|
||||
def compile_items
|
||||
GameData::Item::DATA.clear
|
||||
item_names = []
|
||||
item_names_plural = []
|
||||
item_descriptions = []
|
||||
# Read each line of items.txt at a time and compile it into an item
|
||||
pbCompilerEachCommentedLine("PBS/items.txt") { |line, line_no|
|
||||
line = pbGetCsvRecord(line, line_no, [0, "vnssuusuuUN"])
|
||||
item_number = line[0]
|
||||
item_symbol = line[1].to_sym
|
||||
if GameData::Item::DATA[item_number]
|
||||
raise _INTL("Item ID number '{1}' is used twice.\r\n{2}", item_number, FileLineData.linereport)
|
||||
elsif GameData::Item::DATA[item_symbol]
|
||||
raise _INTL("Item ID '{1}' is used twice.\r\n{2}", item_symbol, FileLineData.linereport)
|
||||
end
|
||||
move2anim = [[],[]]
|
||||
=begin
|
||||
anims = load_data("Data/Animations.rxdata")
|
||||
for anim in anims
|
||||
next if !anim || anim.frames.length==1
|
||||
found = false
|
||||
for i in 0...pbanims.length
|
||||
if pbanims[i] && pbanims[i].id==anim.id
|
||||
found = true if pbanims[i].array.length>1
|
||||
break
|
||||
end
|
||||
end
|
||||
pbanims[anim.id] = pbConvertRPGAnimation(anim) if !found
|
||||
end
|
||||
=end
|
||||
for i in 0...pbanims.length
|
||||
next if !pbanims[i]
|
||||
if pbanims[i].name[/^OppMove\:\s*(.*)$/]
|
||||
if GameData::Move.exists?($~[1])
|
||||
moveid = GameData::Move.get($~[1]).id_number
|
||||
move2anim[1][moveid] = i
|
||||
end
|
||||
elsif pbanims[i].name[/^Move\:\s*(.*)$/]
|
||||
if GameData::Move.exists?($~[1])
|
||||
moveid = GameData::Move.get($~[1]).id_number
|
||||
move2anim[0][moveid] = i
|
||||
end
|
||||
end
|
||||
end
|
||||
save_data(move2anim,"Data/move2anim.dat")
|
||||
save_data(pbanims,"Data/PkmnAnimations.rxdata")
|
||||
# Construct item hash
|
||||
item_hash = {
|
||||
:id_number => item_number,
|
||||
:id => item_symbol,
|
||||
:name => line[2],
|
||||
:name_plural => line[3],
|
||||
:pocket => line[4],
|
||||
:price => line[5],
|
||||
:description => line[6],
|
||||
:field_use => line[7],
|
||||
:battle_use => line[8],
|
||||
:type => line[9]
|
||||
}
|
||||
item_hash[:move] = parseMove(line[10]) if !nil_or_empty?(line[10])
|
||||
# Add item's data to records
|
||||
GameData::Item::DATA[item_number] = GameData::Item::DATA[item_symbol] = GameData::Item.new(item_hash)
|
||||
item_names[item_number] = item_hash[:name]
|
||||
item_names_plural[item_number] = item_hash[:name_plural]
|
||||
item_descriptions[item_number] = item_hash[:description]
|
||||
}
|
||||
# Save all data
|
||||
GameData::Item.save
|
||||
MessageTypes.setMessages(MessageTypes::Items, item_names)
|
||||
MessageTypes.setMessages(MessageTypes::ItemPlurals, item_names_plural)
|
||||
MessageTypes.setMessages(MessageTypes::ItemDescriptions, item_descriptions)
|
||||
Graphics.update
|
||||
end
|
||||
|
||||
#=============================================================================
|
||||
# Compile Pokémon
|
||||
# Compile berry plant data
|
||||
#=============================================================================
|
||||
def compile_berry_plants
|
||||
GameData::BerryPlant::DATA.clear
|
||||
pbCompilerEachCommentedLine("PBS/berryplants.txt") { |line, line_no|
|
||||
if line[/^\s*(\w+)\s*=\s*(.*)$/] # Of the format XXX = YYY
|
||||
key = $1
|
||||
value = $2
|
||||
item_symbol = parseItem(key)
|
||||
item_number = GameData::Item.get(item_symbol).id_number
|
||||
line = pbGetCsvRecord(value, line_no, [0, "vuuv"])
|
||||
# Construct berry plant hash
|
||||
berry_plant_hash = {
|
||||
:id => item_symbol,
|
||||
:id_number => item_number,
|
||||
:hours_per_stage => line[0],
|
||||
:drying_per_hour => line[1],
|
||||
:minimum_yield => line[2],
|
||||
:maximum_yield => line[3]
|
||||
}
|
||||
# Add berry plant's data to records
|
||||
GameData::BerryPlant::DATA[item_number] = GameData::BerryPlant::DATA[item_symbol] = GameData::BerryPlant.new(berry_plant_hash)
|
||||
end
|
||||
}
|
||||
# Save all data
|
||||
GameData::BerryPlant.save
|
||||
Graphics.update
|
||||
end
|
||||
|
||||
#=============================================================================
|
||||
# Compile Pokémon data
|
||||
#=============================================================================
|
||||
def compile_pokemon
|
||||
GameData::Species::DATA.clear
|
||||
@@ -713,7 +534,7 @@ module Compiler
|
||||
end
|
||||
|
||||
#=============================================================================
|
||||
# Compile Pokémon forms
|
||||
# Compile Pokémon forms data
|
||||
#=============================================================================
|
||||
def compile_pokemon_forms
|
||||
species_names = []
|
||||
@@ -930,8 +751,8 @@ module Compiler
|
||||
species_hash[species_data.id].each { |move| species_data.tutor_moves.push(move) }
|
||||
end
|
||||
GameData::Species.save
|
||||
pbSavePokemonData
|
||||
pbSavePokemonFormsData
|
||||
Compiler.write_pokemon
|
||||
Compiler.write_pokemon_forms
|
||||
begin
|
||||
File.delete("PBS/tm.txt")
|
||||
rescue SystemCallError
|
||||
@@ -1003,7 +824,7 @@ module Compiler
|
||||
end
|
||||
|
||||
#=============================================================================
|
||||
# Compile wild encounters
|
||||
# Compile wild encounter data
|
||||
#=============================================================================
|
||||
def compile_encounters
|
||||
lines = []
|
||||
@@ -1110,7 +931,7 @@ module Compiler
|
||||
end
|
||||
|
||||
#=============================================================================
|
||||
# Compile trainer types
|
||||
# Compile trainer type data
|
||||
#=============================================================================
|
||||
def compile_trainer_types
|
||||
GameData::TrainerType::DATA.clear
|
||||
@@ -1155,7 +976,7 @@ module Compiler
|
||||
end
|
||||
|
||||
#=============================================================================
|
||||
# Compile individual trainers
|
||||
# Compile individual trainer data
|
||||
#=============================================================================
|
||||
def compile_trainers
|
||||
trainer_info_types = TrainerData::SCHEMA
|
||||
@@ -1355,47 +1176,6 @@ module Compiler
|
||||
#=============================================================================
|
||||
# Compile Battle Tower and other Cups trainers/Pokémon
|
||||
#=============================================================================
|
||||
def compile_battle_tower_trainers(filename)
|
||||
sections = []
|
||||
requiredtypes = {
|
||||
"Type" => [0, "e", :TrainerType],
|
||||
"Name" => [1, "s"],
|
||||
"BeginSpeech" => [2, "s"],
|
||||
"EndSpeechWin" => [3, "s"],
|
||||
"EndSpeechLose" => [4, "s"],
|
||||
"PokemonNos" => [5, "*u"]
|
||||
}
|
||||
trainernames = []
|
||||
beginspeech = []
|
||||
endspeechwin = []
|
||||
endspeechlose = []
|
||||
if safeExists?(filename)
|
||||
File.open(filename,"rb") { |f|
|
||||
FileLineData.file = filename
|
||||
pbEachFileSectionEx(f) { |section,name|
|
||||
rsection = []
|
||||
for key in section.keys
|
||||
FileLineData.setSection(name,key,section[key])
|
||||
schema = requiredtypes[key]
|
||||
next if !schema
|
||||
record = pbGetCsvRecord(section[key],0,schema)
|
||||
rsection[schema[0]] = record
|
||||
end
|
||||
trainernames.push(rsection[1])
|
||||
beginspeech.push(rsection[2])
|
||||
endspeechwin.push(rsection[3])
|
||||
endspeechlose.push(rsection[4])
|
||||
sections.push(rsection)
|
||||
}
|
||||
}
|
||||
end
|
||||
MessageTypes.addMessagesAsHash(MessageTypes::TrainerNames,trainernames)
|
||||
MessageTypes.addMessagesAsHash(MessageTypes::BeginSpeech,beginspeech)
|
||||
MessageTypes.addMessagesAsHash(MessageTypes::EndSpeechWin,endspeechwin)
|
||||
MessageTypes.addMessagesAsHash(MessageTypes::EndSpeechLose,endspeechlose)
|
||||
return sections
|
||||
end
|
||||
|
||||
def compile_trainer_lists
|
||||
btTrainersRequiredTypes = {
|
||||
"Trainers" => [0, "s"],
|
||||
@@ -1462,4 +1242,176 @@ module Compiler
|
||||
}
|
||||
save_data(sections,"Data/trainer_lists.dat")
|
||||
end
|
||||
|
||||
def compile_battle_tower_trainers(filename)
|
||||
sections = []
|
||||
requiredtypes = {
|
||||
"Type" => [0, "e", :TrainerType],
|
||||
"Name" => [1, "s"],
|
||||
"BeginSpeech" => [2, "s"],
|
||||
"EndSpeechWin" => [3, "s"],
|
||||
"EndSpeechLose" => [4, "s"],
|
||||
"PokemonNos" => [5, "*u"]
|
||||
}
|
||||
trainernames = []
|
||||
beginspeech = []
|
||||
endspeechwin = []
|
||||
endspeechlose = []
|
||||
if safeExists?(filename)
|
||||
File.open(filename,"rb") { |f|
|
||||
FileLineData.file = filename
|
||||
pbEachFileSectionEx(f) { |section,name|
|
||||
rsection = []
|
||||
for key in section.keys
|
||||
FileLineData.setSection(name,key,section[key])
|
||||
schema = requiredtypes[key]
|
||||
next if !schema
|
||||
record = pbGetCsvRecord(section[key],0,schema)
|
||||
rsection[schema[0]] = record
|
||||
end
|
||||
trainernames.push(rsection[1])
|
||||
beginspeech.push(rsection[2])
|
||||
endspeechwin.push(rsection[3])
|
||||
endspeechlose.push(rsection[4])
|
||||
sections.push(rsection)
|
||||
}
|
||||
}
|
||||
end
|
||||
MessageTypes.addMessagesAsHash(MessageTypes::TrainerNames,trainernames)
|
||||
MessageTypes.addMessagesAsHash(MessageTypes::BeginSpeech,beginspeech)
|
||||
MessageTypes.addMessagesAsHash(MessageTypes::EndSpeechWin,endspeechwin)
|
||||
MessageTypes.addMessagesAsHash(MessageTypes::EndSpeechLose,endspeechlose)
|
||||
return sections
|
||||
end
|
||||
|
||||
#=============================================================================
|
||||
# Compile metadata
|
||||
#=============================================================================
|
||||
def compile_metadata
|
||||
GameData::Metadata::DATA.clear
|
||||
GameData::MapMetadata::DATA.clear
|
||||
# Read from PBS file
|
||||
File.open("PBS/metadata.txt", "rb") { |f|
|
||||
FileLineData.file = "PBS/metadata.txt" # For error reporting
|
||||
# Read a whole section's lines at once, then run through this code.
|
||||
# contents is a hash containing all the XXX=YYY lines in that section, where
|
||||
# the keys are the XXX and the values are the YYY (as unprocessed strings).
|
||||
pbEachFileSection(f) { |contents, map_id|
|
||||
schema = (map_id == 0) ? GameData::Metadata::SCHEMA : GameData::MapMetadata::SCHEMA
|
||||
# Go through schema hash of compilable data and compile this section
|
||||
for key in schema.keys
|
||||
FileLineData.setSection(map_id, key, contents[key]) # For error reporting
|
||||
# Skip empty properties, or raise an error if a required property is
|
||||
# empty
|
||||
if contents[key].nil?
|
||||
if map_id == 0 && ["Home", "PlayerA"].include?(key)
|
||||
raise _INTL("The entry {1} is required in PBS/metadata.txt section 0.", key)
|
||||
end
|
||||
next
|
||||
end
|
||||
# Compile value for key
|
||||
value = pbGetCsvRecord(contents[key], key, schema[key])
|
||||
value = nil if value.is_a?(Array) && value.length == 0
|
||||
contents[key] = value
|
||||
end
|
||||
if map_id == 0 # Global metadata
|
||||
# Construct metadata hash
|
||||
metadata_hash = {
|
||||
:id => map_id,
|
||||
:home => contents["Home"],
|
||||
:wild_battle_BGM => contents["WildBattleBGM"],
|
||||
:trainer_battle_BGM => contents["TrainerBattleBGM"],
|
||||
:wild_victory_ME => contents["WildVictoryME"],
|
||||
:trainer_victory_ME => contents["TrainerVictoryME"],
|
||||
:wild_capture_ME => contents["WildCaptureME"],
|
||||
:surf_BGM => contents["SurfBGM"],
|
||||
:bicycle_BGM => contents["BicycleBGM"],
|
||||
:player_A => contents["PlayerA"],
|
||||
:player_B => contents["PlayerB"],
|
||||
:player_C => contents["PlayerC"],
|
||||
:player_D => contents["PlayerD"],
|
||||
:player_E => contents["PlayerE"],
|
||||
:player_F => contents["PlayerF"],
|
||||
:player_G => contents["PlayerG"],
|
||||
:player_H => contents["PlayerH"]
|
||||
}
|
||||
# Add metadata's data to records
|
||||
GameData::Metadata::DATA[map_id] = GameData::Metadata.new(metadata_hash)
|
||||
else # Map metadata
|
||||
# Construct metadata hash
|
||||
metadata_hash = {
|
||||
:id => map_id,
|
||||
:outdoor_map => contents["Outdoor"],
|
||||
:announce_location => contents["ShowArea"],
|
||||
:can_bicycle => contents["Bicycle"],
|
||||
:always_bicycle => contents["BicycleAlways"],
|
||||
:teleport_destination => contents["HealingSpot"],
|
||||
:weather => contents["Weather"],
|
||||
:town_map_position => contents["MapPosition"],
|
||||
:dive_map_id => contents["DiveMap"],
|
||||
:dark_map => contents["DarkMap"],
|
||||
:safari_map => contents["SafariMap"],
|
||||
:snap_edges => contents["SnapEdges"],
|
||||
:random_dungeon => contents["Dungeon"],
|
||||
:battle_background => contents["BattleBack"],
|
||||
:wild_battle_BGM => contents["WildBattleBGM"],
|
||||
:trainer_battle_BGM => contents["TrainerBattleBGM"],
|
||||
:wild_victory_ME => contents["WildVictoryME"],
|
||||
:trainer_victory_ME => contents["TrainerVictoryME"],
|
||||
:wild_capture_ME => contents["WildCaptureME"],
|
||||
:town_map_size => contents["MapSize"],
|
||||
:battle_environment => contents["Environment"]
|
||||
}
|
||||
# Add metadata's data to records
|
||||
GameData::MapMetadata::DATA[map_id] = GameData::MapMetadata.new(metadata_hash)
|
||||
end
|
||||
}
|
||||
}
|
||||
# Save all data
|
||||
GameData::Metadata.save
|
||||
GameData::MapMetadata.save
|
||||
Graphics.update
|
||||
end
|
||||
|
||||
#=============================================================================
|
||||
# Compile battle animations
|
||||
#=============================================================================
|
||||
def compile_animations
|
||||
begin
|
||||
pbanims = load_data("Data/PkmnAnimations.rxdata")
|
||||
rescue
|
||||
pbanims = PBAnimations.new
|
||||
end
|
||||
move2anim = [[],[]]
|
||||
=begin
|
||||
anims = load_data("Data/Animations.rxdata")
|
||||
for anim in anims
|
||||
next if !anim || anim.frames.length==1
|
||||
found = false
|
||||
for i in 0...pbanims.length
|
||||
if pbanims[i] && pbanims[i].id==anim.id
|
||||
found = true if pbanims[i].array.length>1
|
||||
break
|
||||
end
|
||||
end
|
||||
pbanims[anim.id] = pbConvertRPGAnimation(anim) if !found
|
||||
end
|
||||
=end
|
||||
for i in 0...pbanims.length
|
||||
next if !pbanims[i]
|
||||
if pbanims[i].name[/^OppMove\:\s*(.*)$/]
|
||||
if GameData::Move.exists?($~[1])
|
||||
moveid = GameData::Move.get($~[1]).id_number
|
||||
move2anim[1][moveid] = i
|
||||
end
|
||||
elsif pbanims[i].name[/^Move\:\s*(.*)$/]
|
||||
if GameData::Move.exists?($~[1])
|
||||
moveid = GameData::Move.get($~[1]).id_number
|
||||
move2anim[0][moveid] = i
|
||||
end
|
||||
end
|
||||
end
|
||||
save_data(move2anim,"Data/move2anim.dat")
|
||||
save_data(pbanims,"Data/PkmnAnimations.rxdata")
|
||||
end
|
||||
end
|
||||
837
Data/Scripts/022_Compiler/003_Compiler_WritePBS.rb
Normal file
837
Data/Scripts/022_Compiler/003_Compiler_WritePBS.rb
Normal file
@@ -0,0 +1,837 @@
|
||||
module Compiler
|
||||
module_function
|
||||
|
||||
def add_PBS_header_to_file(file)
|
||||
file.write(0xEF.chr)
|
||||
file.write(0xBB.chr)
|
||||
file.write(0xBF.chr)
|
||||
file.write("\# " + _INTL("See the documentation on the wiki to learn how to edit this file.") + "\r\n")
|
||||
end
|
||||
|
||||
#=============================================================================
|
||||
# Save Town Map data to PBS file
|
||||
#=============================================================================
|
||||
def write_town_map
|
||||
mapdata = pbLoadTownMapData
|
||||
return if !mapdata
|
||||
File.open("PBS/townmap.txt","wb") { |f|
|
||||
add_PBS_header_to_file(f)
|
||||
for i in 0...mapdata.length
|
||||
map = mapdata[i]
|
||||
next if !map
|
||||
f.write("\#-------------------------------\r\n")
|
||||
f.write(sprintf("[%d]\r\n",i))
|
||||
rname = pbGetMessage(MessageTypes::RegionNames,i)
|
||||
f.write(sprintf("Name = %s\r\nFilename = %s\r\n",
|
||||
(rname && rname!="") ? rname : _INTL("Unnamed"),
|
||||
csvQuote((map[1].is_a?(Array)) ? map[1][0] : map[1])))
|
||||
for loc in map[2]
|
||||
f.write("Point = ")
|
||||
pbWriteCsvRecord(loc,f,[nil,"uussUUUU"])
|
||||
f.write("\r\n")
|
||||
end
|
||||
end
|
||||
}
|
||||
Graphics.update
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Save map connections to PBS file
|
||||
#===============================================================================
|
||||
def normalizeConnectionPoint(conn)
|
||||
ret = conn.clone
|
||||
if conn[1] < 0 && conn[4] < 0
|
||||
elsif conn[1] < 0 || conn[4] < 0
|
||||
ret[4] = -conn[1]
|
||||
ret[1] = -conn[4]
|
||||
end
|
||||
if conn[2] < 0 && conn[5] < 0
|
||||
elsif conn[2] < 0 || conn[5] < 0
|
||||
ret[5] = -conn[2]
|
||||
ret[2] = -conn[5]
|
||||
end
|
||||
return ret
|
||||
end
|
||||
|
||||
def writeConnectionPoint(map1, x1, y1, map2, x2, y2)
|
||||
dims1 = MapFactoryHelper.getMapDims(map1)
|
||||
dims2 = MapFactoryHelper.getMapDims(map2)
|
||||
if x1 == 0 && x2 == dims2[0]
|
||||
return sprintf("%d,West,%d,%d,East,%d", map1, y1, map2, y2)
|
||||
elsif y1 == 0 && y2 == dims2[1]
|
||||
return sprintf("%d,North,%d,%d,South,%d", map1, x1, map2, x2)
|
||||
elsif x1 == dims1[0] && x2 == 0
|
||||
return sprintf("%d,East,%d,%d,West,%d", map1, y1, map2, y2)
|
||||
elsif y1 == dims1[1] && y2 == 0
|
||||
return sprintf("%d,South,%d,%d,North,%d", map1, x1, map2, x2)
|
||||
end
|
||||
return sprintf("%d,%d,%d,%d,%d,%d", map1, x1, y1, map2, x2, y2)
|
||||
end
|
||||
|
||||
def write_connections
|
||||
conndata = load_data("Data/map_connections.dat") rescue nil
|
||||
return if !conndata
|
||||
mapinfos = pbLoadRxData("Data/MapInfos")
|
||||
File.open("PBS/connections.txt","wb") { |f|
|
||||
add_PBS_header_to_file(f)
|
||||
f.write("\#-------------------------------\r\n")
|
||||
for conn in conndata
|
||||
if mapinfos
|
||||
# Skip if map no longer exists
|
||||
next if !mapinfos[conn[0]] || !mapinfos[conn[3]]
|
||||
f.write(sprintf("# %s (%d) - %s (%d)\r\n",
|
||||
(mapinfos[conn[0]]) ? mapinfos[conn[0]].name : "???", conn[0],
|
||||
(mapinfos[conn[3]]) ? mapinfos[conn[3]].name : "???", conn[3]))
|
||||
end
|
||||
if conn[1].is_a?(String) || conn[4].is_a?(String)
|
||||
f.write(sprintf("%d,%s,%d,%d,%s,%d", conn[0], conn[1], conn[2],
|
||||
conn[3], conn[4], conn[5]))
|
||||
else
|
||||
ret = normalizeConnectionPoint(conn)
|
||||
f.write(writeConnectionPoint(ret[0], ret[1], ret[2], ret[3], ret[4], ret[5]))
|
||||
end
|
||||
f.write("\r\n")
|
||||
end
|
||||
}
|
||||
Graphics.update
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Save phone messages to PBS file
|
||||
#===============================================================================
|
||||
def write_phone
|
||||
data = load_data("Data/phone.dat") rescue nil
|
||||
return if !data
|
||||
File.open("PBS/phone.txt", "wb") { |f|
|
||||
add_PBS_header_to_file(f)
|
||||
f.write("\#-------------------------------\r\n")
|
||||
f.write("[<Generics>]\r\n")
|
||||
f.write(data.generics.join("\r\n") + "\r\n")
|
||||
f.write("\#-------------------------------\r\n")
|
||||
f.write("[<BattleRequests>]\r\n")
|
||||
f.write(data.battleRequests.join("\r\n") + "\r\n")
|
||||
f.write("\#-------------------------------\r\n")
|
||||
f.write("[<GreetingsMorning>]\r\n")
|
||||
f.write(data.greetingsMorning.join("\r\n") + "\r\n")
|
||||
f.write("\#-------------------------------\r\n")
|
||||
f.write("[<GreetingsEvening>]\r\n")
|
||||
f.write(data.greetingsEvening.join("\r\n") + "\r\n")
|
||||
f.write("\#-------------------------------\r\n")
|
||||
f.write("[<Greetings>]\r\n")
|
||||
f.write(data.greetings.join("\r\n") + "\r\n")
|
||||
f.write("\#-------------------------------\r\n")
|
||||
f.write("[<Bodies1>]\r\n")
|
||||
f.write(data.bodies1.join("\r\n") + "\r\n")
|
||||
f.write("\#-------------------------------\r\n")
|
||||
f.write("[<Bodies2>]\r\n")
|
||||
f.write(data.bodies2.join("\r\n") + "\r\n")
|
||||
}
|
||||
Graphics.update
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Save type data to PBS file
|
||||
#===============================================================================
|
||||
def write_types
|
||||
File.open("PBS/types.txt", "wb") { |f|
|
||||
add_PBS_header_to_file(f)
|
||||
# Write each type in turn
|
||||
GameData::Type.each do |type|
|
||||
f.write("\#-------------------------------\r\n")
|
||||
f.write("[#{type.id_number}]\r\n")
|
||||
f.write("Name = #{type.real_name}\r\n")
|
||||
f.write("InternalName = #{type.id.to_s}\r\n")
|
||||
f.write("IsPseudoType = true\r\n") if type.pseudo_type
|
||||
f.write("IsSpecialType = true\r\n") if type.special?
|
||||
f.write("Weaknesses = #{type.weaknesses.join(",")}\r\n") if type.weaknesses.length > 0
|
||||
f.write("Resistances = #{type.resistances.join(",")}\r\n") if type.resistances.length > 0
|
||||
f.write("Immunities = #{type.immunities.join(",")}\r\n") if type.immunities.length > 0
|
||||
end
|
||||
}
|
||||
Graphics.update
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Save ability data to PBS file
|
||||
#===============================================================================
|
||||
def write_abilities
|
||||
File.open("PBS/abilities.txt", "wb") { |f|
|
||||
add_PBS_header_to_file(f)
|
||||
f.write("\#-------------------------------\r\n")
|
||||
GameData::Ability.each do |a|
|
||||
f.write(sprintf("%d,%s,%s,%s\r\n",
|
||||
a.id_number,
|
||||
csvQuote(a.id.to_s),
|
||||
csvQuote(a.real_name),
|
||||
csvQuoteAlways(a.real_description)
|
||||
))
|
||||
end
|
||||
}
|
||||
Graphics.update
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Save move data to PBS file
|
||||
#===============================================================================
|
||||
def write_moves
|
||||
File.open("PBS/moves.txt", "wb") { |f|
|
||||
add_PBS_header_to_file(f)
|
||||
current_type = -1
|
||||
GameData::Move.each do |m|
|
||||
if current_type != m.type
|
||||
current_type = m.type
|
||||
f.write("\#-------------------------------\r\n")
|
||||
end
|
||||
f.write(sprintf("%d,%s,%s,%s,%d,%s,%s,%d,%d,%d,%s,%d,%s,%s\r\n",
|
||||
m.id_number,
|
||||
csvQuote(m.id.to_s),
|
||||
csvQuote(m.real_name),
|
||||
csvQuote(m.function_code),
|
||||
m.base_damage,
|
||||
m.type.to_s,
|
||||
["Physical", "Special", "Status"][m.category],
|
||||
m.accuracy,
|
||||
m.total_pp,
|
||||
m.effect_chance,
|
||||
(getConstantName(PBTargets, m.target) rescue sprintf("%d", m.target)),
|
||||
m.priority,
|
||||
csvQuote(m.flags),
|
||||
csvQuoteAlways(m.real_description)
|
||||
))
|
||||
end
|
||||
}
|
||||
Graphics.update
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Save item data to PBS file
|
||||
#===============================================================================
|
||||
def write_items
|
||||
File.open("PBS/items.txt", "wb") { |f|
|
||||
add_PBS_header_to_file(f)
|
||||
current_pocket = 0
|
||||
GameData::Item.each do |i|
|
||||
if current_pocket != i.pocket
|
||||
current_pocket = i.pocket
|
||||
f.write("\#-------------------------------\r\n")
|
||||
end
|
||||
move_name = (i.move) ? GameData::Move.get(i.move).id.to_s : ""
|
||||
sprintf_text = "%d,%s,%s,%s,%d,%d,%s,%d,%d,%d\r\n"
|
||||
sprintf_text = "%d,%s,%s,%s,%d,%d,%s,%d,%d,%d,%s\r\n" if move_name != ""
|
||||
f.write(sprintf(sprintf_text,
|
||||
i.id_number,
|
||||
csvQuote(i.id.to_s),
|
||||
csvQuote(i.real_name),
|
||||
csvQuote(i.real_name_plural),
|
||||
i.pocket,
|
||||
i.price,
|
||||
csvQuoteAlways(i.real_description),
|
||||
i.field_use,
|
||||
i.battle_use,
|
||||
i.type,
|
||||
csvQuote(move_name)
|
||||
))
|
||||
end
|
||||
}
|
||||
Graphics.update
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Save berry plant data to PBS file
|
||||
#===============================================================================
|
||||
def write_berry_plants
|
||||
File.open("PBS/berryplants.txt", "wb") { |f|
|
||||
add_PBS_header_to_file(f)
|
||||
f.write("\#-------------------------------\r\n")
|
||||
GameData::BerryPlant.each do |bp|
|
||||
f.write(sprintf("%s = %d,%d,%d,%d\r\n",
|
||||
csvQuote(bp.id.to_s),
|
||||
bp.hours_per_stage,
|
||||
bp.drying_per_hour,
|
||||
bp.minimum_yield,
|
||||
bp.maximum_yield
|
||||
))
|
||||
end
|
||||
}
|
||||
Graphics.update
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Save Pokémon data to PBS file
|
||||
#===============================================================================
|
||||
def write_pokemon
|
||||
File.open("PBS/pokemon.txt", "wb") { |f|
|
||||
add_PBS_header_to_file(f)
|
||||
GameData::Species.each do |species|
|
||||
next if species.form != 0
|
||||
pbSetWindowText(_INTL("Writing species {1}...", species.id_number))
|
||||
Graphics.update if species.id_number % 50 == 0
|
||||
f.write("\#-------------------------------\r\n")
|
||||
f.write(sprintf("[%d]\r\n", species.id_number))
|
||||
f.write(sprintf("Name = %s\r\n", species.real_name))
|
||||
f.write(sprintf("InternalName = %s\r\n", species.species))
|
||||
f.write(sprintf("Type1 = %s\r\n", species.type1))
|
||||
f.write(sprintf("Type2 = %s\r\n", species.type2)) if species.type2 != species.type1
|
||||
f.write(sprintf("BaseStats = %s\r\n", species.base_stats.join(",")))
|
||||
f.write(sprintf("GenderRate = %s\r\n", getConstantName(PBGenderRates, species.gender_rate)))
|
||||
f.write(sprintf("GrowthRate = %s\r\n", getConstantName(PBGrowthRates, species.growth_rate)))
|
||||
f.write(sprintf("BaseEXP = %d\r\n", species.base_exp))
|
||||
f.write(sprintf("EffortPoints = %s\r\n", species.evs.join(",")))
|
||||
f.write(sprintf("Rareness = %d\r\n", species.catch_rate))
|
||||
f.write(sprintf("Happiness = %d\r\n", species.happiness))
|
||||
if species.abilities.length > 0
|
||||
f.write(sprintf("Abilities = %s\r\n", species.abilities.join(",")))
|
||||
end
|
||||
if species.hidden_abilities.length > 0
|
||||
f.write(sprintf("HiddenAbility = %s\r\n", species.hidden_abilities.join(",")))
|
||||
end
|
||||
if species.moves.length > 0
|
||||
f.write(sprintf("Moves = %s\r\n", species.moves.join(",")))
|
||||
end
|
||||
if species.tutor_moves.length > 0
|
||||
f.write(sprintf("TutorMoves = %s\r\n", species.tutor_moves.join(",")))
|
||||
end
|
||||
if species.egg_moves.length > 0
|
||||
f.write(sprintf("EggMoves = %s\r\n", species.egg_moves.join(",")))
|
||||
end
|
||||
if species.egg_groups.length > 0
|
||||
f.write("Compatibility = ")
|
||||
species.egg_groups.each_with_index do |group, i|
|
||||
f.write(",") if i > 0
|
||||
f.write(getConstantName(PBEggGroups, group))
|
||||
end
|
||||
f.write("\r\n")
|
||||
end
|
||||
f.write(sprintf("StepsToHatch = %d\r\n", species.hatch_steps))
|
||||
f.write(sprintf("Height = %.1f\r\n", species.height / 10.0))
|
||||
f.write(sprintf("Weight = %.1f\r\n", species.weight / 10.0))
|
||||
f.write(sprintf("Color = %s\r\n", getConstantName(PBColors, species.color)))
|
||||
f.write(sprintf("Shape = %d\r\n", species.shape))
|
||||
f.write(sprintf("Habitat = %s\r\n", getConstantName(PBHabitats, species.habitat))) if species.habitat != PBHabitats::None
|
||||
f.write(sprintf("Kind = %s\r\n", species.real_category))
|
||||
f.write(sprintf("Pokedex = %s\r\n", species.real_pokedex_entry))
|
||||
f.write(sprintf("FormName = %s\r\n", species.real_form_name)) if species.real_form_name && !species.real_form_name.empty?
|
||||
f.write(sprintf("Generation = %d\r\n", species.generation)) if species.generation != 0
|
||||
f.write(sprintf("WildItemCommon = %s\r\n", species.wild_item_common)) if species.wild_item_common
|
||||
f.write(sprintf("WildItemUncommon = %s\r\n", species.wild_item_uncommon)) if species.wild_item_uncommon
|
||||
f.write(sprintf("WildItemRare = %s\r\n", species.wild_item_rare)) if species.wild_item_rare
|
||||
f.write(sprintf("BattlerPlayerX = %d\r\n", species.back_sprite_x))
|
||||
f.write(sprintf("BattlerPlayerY = %d\r\n", species.back_sprite_y))
|
||||
f.write(sprintf("BattlerEnemyX = %d\r\n", species.front_sprite_x))
|
||||
f.write(sprintf("BattlerEnemyY = %d\r\n", species.front_sprite_y))
|
||||
f.write(sprintf("BattlerAltitude = %d\r\n", species.front_sprite_altitude)) if species.front_sprite_altitude != 0
|
||||
f.write(sprintf("BattlerShadowX = %d\r\n", species.shadow_x))
|
||||
f.write(sprintf("BattlerShadowSize = %d\r\n", species.shadow_size))
|
||||
if species.evolutions.any? { |evo| !evo[3] }
|
||||
f.write("Evolutions = ")
|
||||
need_comma = false
|
||||
species.evolutions.each do |evo|
|
||||
next if evo[3] # Skip prevolution entries
|
||||
f.write(",") if need_comma
|
||||
need_comma = true
|
||||
f.write(sprintf("%s,%s,", evo[0], getConstantName(PBEvolution, evo[1])))
|
||||
param_type = PBEvolution.getFunction(evo[1], "parameterType")
|
||||
has_param = !PBEvolution.hasFunction?(evo[1], "parameterType") || param_type != nil
|
||||
next if !has_param
|
||||
if param_type
|
||||
if GameData.const_defined?(param_type.to_sym)
|
||||
f.write(evo[2].to_s)
|
||||
else
|
||||
f.write(getConstantName(param_type, evo[2]))
|
||||
end
|
||||
else
|
||||
f.write(evo[2].to_s)
|
||||
end
|
||||
end
|
||||
f.write("\r\n")
|
||||
end
|
||||
f.write(sprintf("Incense = %s\r\n", species.incense)) if species.incense
|
||||
end
|
||||
}
|
||||
Graphics.update
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Save Pokémon forms data to PBS file
|
||||
#===============================================================================
|
||||
def write_pokemon_forms
|
||||
File.open("PBS/pokemonforms.txt", "wb") { |f|
|
||||
add_PBS_header_to_file(f)
|
||||
GameData::Species.each do |species|
|
||||
next if species.form == 0
|
||||
base_species = GameData::Species.get(species.species)
|
||||
pbSetWindowText(_INTL("Writing species {1}...", species.id_number))
|
||||
Graphics.update if species.id_number % 50 == 0
|
||||
f.write("\#-------------------------------\r\n")
|
||||
f.write(sprintf("[%s,%d]\r\n", species.species, species.form))
|
||||
f.write(sprintf("FormName = %s\r\n", species.real_form_name)) if species.real_form_name && !species.real_form_name.empty?
|
||||
f.write(sprintf("PokedexForm = %d\r\n", species.pokedex_form)) if species.pokedex_form != species.form
|
||||
f.write(sprintf("MegaStone = %s\r\n", species.mega_stone)) if species.mega_stone
|
||||
f.write(sprintf("MegaMove = %s\r\n", species.mega_move)) if species.mega_move
|
||||
f.write(sprintf("UnmegaForm = %d\r\n", species.unmega_form)) if species.unmega_form != 0
|
||||
f.write(sprintf("MegaMessage = %d\r\n", species.mega_message)) if species.mega_message != 0
|
||||
if species.type1 != base_species.type1 || species.type2 != base_species.type2
|
||||
f.write(sprintf("Type1 = %s\r\n", species.type1))
|
||||
f.write(sprintf("Type2 = %s\r\n", species.type2)) if species.type2 != species.type1
|
||||
end
|
||||
f.write(sprintf("BaseStats = %s\r\n", species.base_stats.join(","))) if species.base_stats != base_species.base_stats
|
||||
f.write(sprintf("BaseEXP = %d\r\n", species.base_exp)) if species.base_exp != base_species.base_exp
|
||||
f.write(sprintf("EffortPoints = %s\r\n", species.evs.join(","))) if species.evs != base_species.evs
|
||||
f.write(sprintf("Rareness = %d\r\n", species.catch_rate)) if species.catch_rate != base_species.catch_rate
|
||||
f.write(sprintf("Happiness = %d\r\n", species.happiness)) if species.happiness != base_species.happiness
|
||||
if species.abilities.length > 0 && species.abilities != base_species.abilities
|
||||
f.write(sprintf("Abilities = %s\r\n", species.abilities.join(",")))
|
||||
end
|
||||
if species.hidden_abilities.length > 0 && species.hidden_abilities != base_species.hidden_abilities
|
||||
f.write(sprintf("HiddenAbility = %s\r\n", species.hidden_abilities.join(",")))
|
||||
end
|
||||
if species.moves.length > 0 && species.moves != base_species.moves
|
||||
f.write(sprintf("Moves = %s\r\n", species.moves.join(",")))
|
||||
end
|
||||
if species.tutor_moves.length > 0 && species.tutor_moves != base_species.tutor_moves
|
||||
f.write(sprintf("TutorMoves = %s\r\n", species.tutor_moves.join(",")))
|
||||
end
|
||||
if species.egg_moves.length > 0 && species.egg_moves != base_species.egg_moves
|
||||
f.write(sprintf("EggMoves = %s\r\n", species.egg_moves.join(",")))
|
||||
end
|
||||
if species.egg_groups.length > 0 && species.egg_groups != base_species.egg_groups
|
||||
f.write("Compatibility = ")
|
||||
species.egg_groups.each_with_index do |group, i|
|
||||
f.write(",") if i > 0
|
||||
f.write(getConstantName(PBEggGroups, group))
|
||||
end
|
||||
f.write("\r\n")
|
||||
end
|
||||
f.write(sprintf("StepsToHatch = %d\r\n", species.hatch_steps)) if species.hatch_steps != base_species.hatch_steps
|
||||
f.write(sprintf("Height = %.1f\r\n", species.height / 10.0)) if species.height != base_species.height
|
||||
f.write(sprintf("Weight = %.1f\r\n", species.weight / 10.0)) if species.weight != base_species.weight
|
||||
f.write(sprintf("Color = %s\r\n", getConstantName(PBColors, species.color))) if species.color != base_species.color
|
||||
f.write(sprintf("Shape = %d\r\n", species.shape)) if species.shape != base_species.shape
|
||||
if species.habitat != PBHabitats::None && species.habitat != base_species.habitat
|
||||
f.write(sprintf("Habitat = %s\r\n", getConstantName(PBHabitats, species.habitat)))
|
||||
end
|
||||
f.write(sprintf("Kind = %s\r\n", species.real_category)) if species.real_category != base_species.real_category
|
||||
f.write(sprintf("Pokedex = %s\r\n", species.real_pokedex_entry)) if species.real_pokedex_entry != base_species.real_pokedex_entry
|
||||
f.write(sprintf("Generation = %d\r\n", species.generation)) if species.generation != base_species.generation
|
||||
if species.wild_item_common != base_species.wild_item_common ||
|
||||
species.wild_item_uncommon != base_species.wild_item_uncommon ||
|
||||
species.wild_item_rare != base_species.wild_item_rare
|
||||
f.write(sprintf("WildItemCommon = %s\r\n", species.wild_item_common)) if species.wild_item_common
|
||||
f.write(sprintf("WildItemUncommon = %s\r\n", species.wild_item_uncommon)) if species.wild_item_uncommon
|
||||
f.write(sprintf("WildItemRare = %s\r\n", species.wild_item_rare)) if species.wild_item_rare
|
||||
end
|
||||
f.write(sprintf("BattlerPlayerX = %d\r\n", species.back_sprite_x)) if species.back_sprite_x != base_species.back_sprite_x
|
||||
f.write(sprintf("BattlerPlayerY = %d\r\n", species.back_sprite_y)) if species.back_sprite_y != base_species.back_sprite_y
|
||||
f.write(sprintf("BattlerEnemyX = %d\r\n", species.front_sprite_x)) if species.front_sprite_x != base_species.front_sprite_x
|
||||
f.write(sprintf("BattlerEnemyY = %d\r\n", species.front_sprite_y)) if species.front_sprite_y != base_species.front_sprite_y
|
||||
f.write(sprintf("BattlerAltitude = %d\r\n", species.front_sprite_altitude)) if species.front_sprite_altitude != base_species.front_sprite_altitude
|
||||
f.write(sprintf("BattlerShadowX = %d\r\n", species.shadow_x)) if species.shadow_x != base_species.shadow_x
|
||||
f.write(sprintf("BattlerShadowSize = %d\r\n", species.shadow_size)) if species.shadow_size != base_species.shadow_size
|
||||
if species.evolutions != base_species.evolutions && species.evolutions.any? { |evo| !evo[3] }
|
||||
f.write("Evolutions = ")
|
||||
need_comma = false
|
||||
species.evolutions.each do |evo|
|
||||
next if evo[3] # Skip prevolution entries
|
||||
f.write(",") if need_comma
|
||||
need_comma = true
|
||||
f.write(sprintf("%s,%s,", evo[0], getConstantName(PBEvolution, evo[1])))
|
||||
param_type = PBEvolution.getFunction(evo[1], "parameterType")
|
||||
has_param = !PBEvolution.hasFunction?(evo[1], "parameterType") || param_type != nil
|
||||
next if !has_param
|
||||
if param_type
|
||||
if GameData.const_defined?(param_type.to_sym)
|
||||
f.write(evo[2].to_s)
|
||||
else
|
||||
f.write(getConstantName(param_type, evo[2]))
|
||||
end
|
||||
else
|
||||
f.write(evo[2].to_s)
|
||||
end
|
||||
end
|
||||
f.write("\r\n")
|
||||
end
|
||||
end
|
||||
}
|
||||
Graphics.update
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Save Shadow movesets to PBS file
|
||||
#===============================================================================
|
||||
def write_shadow_movesets
|
||||
shadow_movesets = pbLoadShadowMovesets
|
||||
File.open("PBS/shadowmoves.txt", "wb") { |f|
|
||||
add_PBS_header_to_file(f)
|
||||
f.write("\#-------------------------------\r\n")
|
||||
GameData::Species.each do |species_data|
|
||||
moveset = shadow_movesets[species_data.id]
|
||||
next if !moveset || moveset.length == 0
|
||||
f.write(sprintf("%s = %s\r\n", species_data.id, moveset.join(",")))
|
||||
end
|
||||
}
|
||||
Graphics.update
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Save Regional Dexes to PBS file
|
||||
#===============================================================================
|
||||
def write_regional_dexes
|
||||
dex_lists = pbLoadRegionalDexes
|
||||
File.open("PBS/regionaldexes.txt", "wb") { |f|
|
||||
add_PBS_header_to_file(f)
|
||||
# Write each Dex list in turn
|
||||
dex_lists.each_with_index do |list, index|
|
||||
f.write("\#-------------------------------\r\n")
|
||||
f.write("[#{index}]")
|
||||
comma = false
|
||||
current_family = nil
|
||||
list.each do |species|
|
||||
next if !species
|
||||
if current_family && current_family.include?(species)
|
||||
f.write(",") if comma
|
||||
else
|
||||
current_family = EvolutionHelper.all_related_species(species)
|
||||
comma = false
|
||||
f.write("\r\n")
|
||||
end
|
||||
f.write(species)
|
||||
comma = true
|
||||
end
|
||||
f.write("\r\n")
|
||||
end
|
||||
}
|
||||
Graphics.update
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Save wild encounter data to PBS file
|
||||
#===============================================================================
|
||||
def write_encounters
|
||||
encdata = pbLoadEncountersData
|
||||
return if !encdata
|
||||
mapinfos = pbLoadRxData("Data/MapInfos")
|
||||
File.open("PBS/encounters.txt","wb") { |f|
|
||||
add_PBS_header_to_file(f)
|
||||
sortedkeys = encdata.keys.sort
|
||||
for i in sortedkeys
|
||||
next if !encdata[i]
|
||||
e = encdata[i]
|
||||
mapname = ""
|
||||
if mapinfos[i]
|
||||
map = mapinfos[i].name
|
||||
mapname = " # #{map}"
|
||||
end
|
||||
f.write("\#-------------------------------\r\n")
|
||||
f.write(sprintf("%03d%s\r\n",i,mapname))
|
||||
f.write(sprintf("%d,%d,%d\r\n",e[0][EncounterTypes::Land],
|
||||
e[0][EncounterTypes::Cave],e[0][EncounterTypes::Water]))
|
||||
for j in 0...e[1].length
|
||||
enc = e[1][j]
|
||||
next if !enc
|
||||
f.write(sprintf("%s\r\n",EncounterTypes::Names[j]))
|
||||
for k in 0...EncounterTypes::EnctypeChances[j].length
|
||||
next if !enc[k]
|
||||
encentry = enc[k]
|
||||
if encentry[1]==encentry[2]
|
||||
f.write(sprintf(" %s,%d\r\n",encentry[0],encentry[1]))
|
||||
else
|
||||
f.write(sprintf(" %s,%d,%d\r\n",encentry[0],encentry[1],encentry[2]))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
}
|
||||
Graphics.update
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Save trainer type data to PBS file
|
||||
#===============================================================================
|
||||
def write_trainer_types
|
||||
File.open("PBS/trainertypes.txt", "wb") { |f|
|
||||
add_PBS_header_to_file(f)
|
||||
f.write("\#-------------------------------\r\n")
|
||||
GameData::TrainerType.each do |t|
|
||||
f.write(sprintf("%d,%s,%s,%d,%s,%s,%s,%s,%s,%s\r\n",
|
||||
t.id_number,
|
||||
csvQuote(t.id.to_s),
|
||||
csvQuote(t.real_name),
|
||||
t.base_money,
|
||||
csvQuote(t.battle_BGM),
|
||||
csvQuote(t.victory_ME),
|
||||
csvQuote(t.intro_ME),
|
||||
["Male", "Female", "Mixed"][t.gender],
|
||||
(t.skill_level == t.base_money) ? "" : t.skill_level.to_s,
|
||||
csvQuote(t.skill_code)
|
||||
))
|
||||
end
|
||||
}
|
||||
Graphics.update
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Save individual trainer data to PBS file
|
||||
#===============================================================================
|
||||
def write_trainers
|
||||
data = pbLoadTrainersData
|
||||
return if !data
|
||||
File.open("PBS/trainers.txt","wb") { |f|
|
||||
add_PBS_header_to_file(f)
|
||||
for trainer in data
|
||||
trtypename = trainer[0].to_s
|
||||
next if !trtypename
|
||||
f.write("\#-------------------------------\r\n")
|
||||
# Section
|
||||
trainername = trainer[1] ? trainer[1].gsub(/,/,";") : "???"
|
||||
if trainer[4]==0
|
||||
f.write(sprintf("[%s,%s]\r\n",trtypename,trainername))
|
||||
else
|
||||
f.write(sprintf("[%s,%s,%d]\r\n",trtypename,trainername,trainer[4]))
|
||||
end
|
||||
# Trainer's items
|
||||
if trainer[2] && trainer[2].length>0
|
||||
itemstring = ""
|
||||
for i in 0...trainer[2].length
|
||||
itemstring.concat(",") if i > 0
|
||||
itemstring.concat(trainer[2][i].to_s)
|
||||
end
|
||||
f.write(sprintf("Items = %s\r\n",itemstring)) if itemstring!=""
|
||||
end
|
||||
# Lose texts
|
||||
if trainer[5] && trainer[5]!=""
|
||||
f.write(sprintf("LoseText = %s\r\n",csvQuoteAlways(trainer[5])))
|
||||
end
|
||||
# Pokémon
|
||||
for poke in trainer[3]
|
||||
f.write(sprintf("Pokemon = %s,%d\r\n",poke[TrainerData::SPECIES],poke[TrainerData::LEVEL]))
|
||||
if poke[TrainerData::NAME] && poke[TrainerData::NAME]!=""
|
||||
f.write(sprintf(" Name = %s\r\n",poke[TrainerData::NAME]))
|
||||
end
|
||||
if poke[TrainerData::FORM]
|
||||
f.write(sprintf(" Form = %d\r\n",poke[TrainerData::FORM]))
|
||||
end
|
||||
if poke[TrainerData::GENDER]
|
||||
f.write(sprintf(" Gender = %s\r\n",(poke[TrainerData::GENDER]==1) ? "female" : "male"))
|
||||
end
|
||||
if poke[TrainerData::SHINY]
|
||||
f.write(" Shiny = yes\r\n")
|
||||
end
|
||||
if poke[TrainerData::SHADOW]
|
||||
f.write(" Shadow = yes\r\n")
|
||||
end
|
||||
if poke[TrainerData::MOVES] && poke[TrainerData::MOVES].length>0
|
||||
movestring = ""
|
||||
for i in 0...poke[TrainerData::MOVES].length
|
||||
movename = GameData::Move.get(poke[TrainerData::MOVES][i]).id.to_s
|
||||
next if !movename
|
||||
movestring.concat(",") if i>0
|
||||
movestring.concat(movename)
|
||||
end
|
||||
f.write(sprintf(" Moves = %s\r\n",movestring)) if movestring!=""
|
||||
end
|
||||
if poke[TrainerData::ABILITY]
|
||||
f.write(sprintf(" Ability = %s\r\n",poke[TrainerData::ABILITY].to_s))
|
||||
end
|
||||
if poke[TrainerData::ITEM]
|
||||
f.write(sprintf(" Item = %s\r\n",poke[TrainerData::ITEM].to_s))
|
||||
end
|
||||
if poke[TrainerData::NATURE]
|
||||
nature = getConstantName(PBNatures,poke[TrainerData::NATURE]) rescue nil
|
||||
f.write(sprintf(" Nature = %s\r\n",nature)) if nature
|
||||
end
|
||||
if poke[TrainerData::IV] && poke[TrainerData::IV].length>0
|
||||
f.write(sprintf(" IV = %d",poke[TrainerData::IV][0]))
|
||||
if poke[TrainerData::IV].length>1
|
||||
for i in 1...6
|
||||
f.write(sprintf(",%d",(i<poke[TrainerData::IV].length) ? poke[TrainerData::IV][i] : poke[TrainerData::IV][0]))
|
||||
end
|
||||
end
|
||||
f.write("\r\n")
|
||||
end
|
||||
if poke[TrainerData::EV] && poke[TrainerData::EV].length>0
|
||||
f.write(sprintf(" EV = %d",poke[TrainerData::EV][0]))
|
||||
if poke[TrainerData::EV].length>1
|
||||
for i in 1...6
|
||||
f.write(sprintf(",%d",(i<poke[TrainerData::EV].length) ? poke[TrainerData::EV][i] : poke[TrainerData::EV][0]))
|
||||
end
|
||||
end
|
||||
f.write("\r\n")
|
||||
end
|
||||
if poke[TrainerData::HAPPINESS]
|
||||
f.write(sprintf(" Happiness = %d\r\n",poke[TrainerData::HAPPINESS]))
|
||||
end
|
||||
if poke[TrainerData::BALL]
|
||||
f.write(sprintf(" Ball = %d\r\n",poke[TrainerData::BALL]))
|
||||
end
|
||||
end
|
||||
end
|
||||
}
|
||||
Graphics.update
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Save trainer list data to PBS file
|
||||
#===============================================================================
|
||||
def write_trainer_lists
|
||||
trainerlists = load_data("Data/trainer_lists.dat") rescue nil
|
||||
return if !trainerlists
|
||||
File.open("PBS/trainerlists.txt","wb") { |f|
|
||||
add_PBS_header_to_file(f)
|
||||
for tr in trainerlists
|
||||
f.write("\#-------------------------------\r\n")
|
||||
f.write(((tr[5]) ? "[DefaultTrainerList]" : "[TrainerList]")+"\r\n")
|
||||
f.write("Trainers = "+tr[3]+"\r\n")
|
||||
f.write("Pokemon = "+tr[4]+"\r\n")
|
||||
f.write("Challenges = "+tr[2].join(",")+"\r\n") if !tr[5]
|
||||
write_battle_tower_trainers(tr[0],"PBS/"+tr[3])
|
||||
write_battle_tower_pokemon(tr[1],"PBS/"+tr[4])
|
||||
end
|
||||
}
|
||||
Graphics.update
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Save Battle Tower trainer data to PBS file
|
||||
#===============================================================================
|
||||
def write_battle_tower_trainers(bttrainers, filename)
|
||||
return if !bttrainers || !filename
|
||||
btTrainersRequiredTypes = {
|
||||
"Type" => [0, "e", nil], # Specifies a trainer
|
||||
"Name" => [1, "s"],
|
||||
"BeginSpeech" => [2, "s"],
|
||||
"EndSpeechWin" => [3, "s"],
|
||||
"EndSpeechLose" => [4, "s"],
|
||||
"PokemonNos" => [5, "*u"]
|
||||
}
|
||||
File.open(filename,"wb") { |f|
|
||||
add_PBS_header_to_file(f)
|
||||
for i in 0...bttrainers.length
|
||||
next if !bttrainers[i]
|
||||
f.write("\#-------------------------------\r\n")
|
||||
f.write(sprintf("[%03d]\r\n",i))
|
||||
for key in btTrainersRequiredTypes.keys
|
||||
schema = btTrainersRequiredTypes[key]
|
||||
record = bttrainers[i][schema[0]]
|
||||
next if record==nil
|
||||
f.write(sprintf("%s = ",key))
|
||||
if key=="Type"
|
||||
f.write(record.to_s)
|
||||
elsif key=="PokemonNos"
|
||||
f.write(record.join(",")) # pbWriteCsvRecord somehow won't work here
|
||||
else
|
||||
pbWriteCsvRecord(record,f,schema)
|
||||
end
|
||||
f.write(sprintf("\r\n"))
|
||||
end
|
||||
end
|
||||
}
|
||||
Graphics.update
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Save Battle Tower Pokémon data to PBS file
|
||||
#===============================================================================
|
||||
def write_battle_tower_pokemon(btpokemon,filename)
|
||||
return if !btpokemon || !filename
|
||||
species = {0=>""}
|
||||
moves = {0=>""}
|
||||
items = {0=>""}
|
||||
natures = {}
|
||||
File.open(filename,"wb") { |f|
|
||||
add_PBS_header_to_file(f)
|
||||
f.write("\#-------------------------------\r\n")
|
||||
for i in 0...btpokemon.length
|
||||
Graphics.update if i%500==0
|
||||
pkmn = btpokemon[i]
|
||||
f.write(pbFastInspect(pkmn,moves,species,items,natures))
|
||||
f.write("\r\n")
|
||||
end
|
||||
}
|
||||
Graphics.update
|
||||
end
|
||||
|
||||
def pbFastInspect(pkmn,moves,species,items,natures)
|
||||
c1 = (species[pkmn.species]) ? species[pkmn.species] : (species[pkmn.species] = GameData::Species.get(pkmn.species).species.to_s)
|
||||
c2 = (items[pkmn.item]) ? items[pkmn.item] : (items[pkmn.item] = GameData::Item.get(pkmn.item).id.to_s)
|
||||
c3 = (natures[pkmn.nature]) ? natures[pkmn.nature] :
|
||||
(natures[pkmn.nature] = getConstantName(PBNatures,pkmn.nature))
|
||||
evlist = ""
|
||||
ev = pkmn.ev
|
||||
evs = ["HP","ATK","DEF","SPD","SA","SD"]
|
||||
for i in 0...ev
|
||||
if ((ev&(1<<i))!=0)
|
||||
evlist += "," if evlist.length>0
|
||||
evlist += evs[i]
|
||||
end
|
||||
end
|
||||
c4 = (moves[pkmn.move1]) ? moves[pkmn.move1] : (moves[pkmn.move1] = GameData::Move.get(pkmn.move1).id.to_s)
|
||||
c5 = (moves[pkmn.move2]) ? moves[pkmn.move2] : (moves[pkmn.move2] = GameData::Move.get(pkmn.move2).id.to_s)
|
||||
c6 = (moves[pkmn.move3]) ? moves[pkmn.move3] : (moves[pkmn.move3] = GameData::Move.get(pkmn.move3).id.to_s)
|
||||
c7 = (moves[pkmn.move4]) ? moves[pkmn.move4] : (moves[pkmn.move4] = GameData::Move.get(pkmn.move4).id.to_s)
|
||||
return "#{c1};#{c2};#{c3};#{evlist};#{c4},#{c5},#{c6},#{c7}"
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Save metadata data to PBS file
|
||||
#===============================================================================
|
||||
def write_metadata
|
||||
File.open("PBS/metadata.txt", "wb") { |f|
|
||||
add_PBS_header_to_file(f)
|
||||
# Write global metadata
|
||||
f.write("\#-------------------------------\r\n")
|
||||
f.write("[000]\r\n")
|
||||
metadata = GameData::Metadata.get
|
||||
schema = GameData::Metadata::SCHEMA
|
||||
keys = schema.keys.sort {|a, b| schema[a][0] <=> schema[b][0] }
|
||||
for key in keys
|
||||
record = metadata.property_from_string(key)
|
||||
next if record.nil?
|
||||
f.write(sprintf("%s = ", key))
|
||||
pbWriteCsvRecord(record, f, schema[key])
|
||||
f.write("\r\n")
|
||||
end
|
||||
# Write map metadata
|
||||
map_infos = pbLoadRxData("Data/MapInfos")
|
||||
schema = GameData::MapMetadata::SCHEMA
|
||||
keys = schema.keys.sort {|a, b| schema[a][0] <=> schema[b][0] }
|
||||
GameData::MapMetadata.each do |map_data|
|
||||
f.write("\#-------------------------------\r\n")
|
||||
f.write(sprintf("[%03d]\r\n", map_data.id))
|
||||
if map_infos && map_infos[map_data.id]
|
||||
f.write(sprintf("# %s\r\n", map_infos[map_data.id].name))
|
||||
end
|
||||
for key in keys
|
||||
record = map_data.property_from_string(key)
|
||||
next if record.nil?
|
||||
f.write(sprintf("%s = ", key))
|
||||
pbWriteCsvRecord(record, f, schema[key])
|
||||
f.write("\r\n")
|
||||
end
|
||||
end
|
||||
}
|
||||
Graphics.update
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Save all data to PBS files
|
||||
#===============================================================================
|
||||
def write_all
|
||||
write_town_map
|
||||
write_connections
|
||||
write_phone
|
||||
write_types
|
||||
write_abilities
|
||||
write_moves
|
||||
write_items
|
||||
write_berry_plants
|
||||
write_pokemon
|
||||
write_pokemon_forms
|
||||
write_shadow_movesets
|
||||
write_regional_dexes
|
||||
write_encounters
|
||||
write_trainer_types
|
||||
write_trainers
|
||||
write_trainer_lists
|
||||
write_metadata
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user