mirror of
https://github.com/infinitefusion/infinitefusion-e18.git
synced 2025-12-07 13:15:01 +00:00
Refactoring and tidying
This commit is contained in:
@@ -4,7 +4,7 @@ class Win32API
|
|||||||
@@GetWindowThreadProcessId = Win32API.new('user32', 'GetWindowThreadProcessId', '%w(l p)', 'l')
|
@@GetWindowThreadProcessId = Win32API.new('user32', 'GetWindowThreadProcessId', '%w(l p)', 'l')
|
||||||
@@FindWindowEx = Win32API.new('user32', 'FindWindowEx', '%w(l l p p)', 'l')
|
@@FindWindowEx = Win32API.new('user32', 'FindWindowEx', '%w(l l p p)', 'l')
|
||||||
|
|
||||||
# Added by Peter O. as a more reliable way to get the RGSS window
|
# Added by Peter O. as a more reliable way to get the RGSS window
|
||||||
def Win32API.pbFindRgssWindow
|
def Win32API.pbFindRgssWindow
|
||||||
return @@RGSSWINDOW if @@RGSSWINDOW
|
return @@RGSSWINDOW if @@RGSSWINDOW
|
||||||
processid = [0].pack('l')
|
processid = [0].pack('l')
|
||||||
@@ -32,73 +32,6 @@ class Win32API
|
|||||||
width,height = rect.unpack('l4')[2..3]
|
width,height = rect.unpack('l4')[2..3]
|
||||||
return width,height
|
return width,height
|
||||||
end
|
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
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -219,12 +219,6 @@ def pbRepositionMessageWindow(msgwindow, linecount=2)
|
|||||||
msgwindow.opacity = 0
|
msgwindow.opacity = 0
|
||||||
end
|
end
|
||||||
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
|
end
|
||||||
|
|
||||||
# internal function
|
# 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
|
class Scene_Map
|
||||||
def updatemini
|
def updatemini
|
||||||
oldmws=$game_temp.message_window_showing
|
oldmws=$game_temp.message_window_showing
|
||||||
oldvis=$game_message ? $game_message.visible : false
|
oldvis=false
|
||||||
$game_temp.message_window_showing=true
|
$game_temp.message_window_showing=true
|
||||||
$game_message.visible=true if $game_message
|
|
||||||
loop do
|
loop do
|
||||||
$game_map.update
|
$game_map.update
|
||||||
$game_player.update
|
$game_player.update
|
||||||
@@ -39,7 +20,6 @@ class Scene_Map
|
|||||||
break if $game_temp.transition_processing
|
break if $game_temp.transition_processing
|
||||||
end
|
end
|
||||||
$game_temp.message_window_showing=oldmws
|
$game_temp.message_window_showing=oldmws
|
||||||
$game_message.visible=oldvis if $game_message
|
|
||||||
@spriteset.update if @spriteset
|
@spriteset.update if @spriteset
|
||||||
@message_window.update if @message_window
|
@message_window.update if @message_window
|
||||||
end
|
end
|
||||||
@@ -52,10 +32,6 @@ class Scene_Battle
|
|||||||
if self.respond_to?("update_basic")
|
if self.respond_to?("update_basic")
|
||||||
update_basic(true)
|
update_basic(true)
|
||||||
update_info_viewport # Update information viewport
|
update_info_viewport # Update information viewport
|
||||||
if $game_message && $game_message.visible
|
|
||||||
@info_viewport.visible = false
|
|
||||||
@message_window.visible = true
|
|
||||||
end
|
|
||||||
else
|
else
|
||||||
oldmws=$game_temp.message_window_showing
|
oldmws=$game_temp.message_window_showing
|
||||||
$game_temp.message_window_showing=true
|
$game_temp.message_window_showing=true
|
||||||
@@ -507,7 +483,6 @@ def pbCreateMessageWindow(viewport=nil,skin=nil)
|
|||||||
msgwindow.back_opacity=MessageConfig::WindowOpacity
|
msgwindow.back_opacity=MessageConfig::WindowOpacity
|
||||||
pbBottomLeftLines(msgwindow,2)
|
pbBottomLeftLines(msgwindow,2)
|
||||||
$game_temp.message_window_showing=true if $game_temp
|
$game_temp.message_window_showing=true if $game_temp
|
||||||
$game_message.visible=true if $game_message
|
|
||||||
skin=MessageConfig.pbGetSpeechFrame() if !skin
|
skin=MessageConfig.pbGetSpeechFrame() if !skin
|
||||||
msgwindow.setSkin(skin)
|
msgwindow.setSkin(skin)
|
||||||
return msgwindow
|
return msgwindow
|
||||||
@@ -515,7 +490,6 @@ end
|
|||||||
|
|
||||||
def pbDisposeMessageWindow(msgwindow)
|
def pbDisposeMessageWindow(msgwindow)
|
||||||
$game_temp.message_window_showing=false if $game_temp
|
$game_temp.message_window_showing=false if $game_temp
|
||||||
$game_message.visible=false if $game_message
|
|
||||||
msgwindow.dispose
|
msgwindow.dispose
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -592,9 +566,8 @@ def pbMessageDisplay(msgwindow,message,letterbyletter=true,commandProc=nil)
|
|||||||
break if text == last_text
|
break if text == last_text
|
||||||
end
|
end
|
||||||
colortag = ""
|
colortag = ""
|
||||||
if ($game_message && $game_message.background>0) ||
|
if $game_system && $game_system.respond_to?("message_frame") &&
|
||||||
($game_system && $game_system.respond_to?("message_frame") &&
|
$game_system.message_frame != 0
|
||||||
$game_system.message_frame != 0)
|
|
||||||
colortag = getSkinColor(msgwindow.windowskin,0,true)
|
colortag = getSkinColor(msgwindow.windowskin,0,true)
|
||||||
else
|
else
|
||||||
colortag = getSkinColor(msgwindow.windowskin,0,isDarkSkin)
|
colortag = getSkinColor(msgwindow.windowskin,0,isDarkSkin)
|
||||||
@@ -674,11 +647,6 @@ def pbMessageDisplay(msgwindow,message,letterbyletter=true,commandProc=nil)
|
|||||||
end
|
end
|
||||||
########## Position message window ##############
|
########## Position message window ##############
|
||||||
pbRepositionMessageWindow(msgwindow,linecount)
|
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
|
if facewindow
|
||||||
pbPositionNearMsgWindow(facewindow,msgwindow,:left)
|
pbPositionNearMsgWindow(facewindow,msgwindow,:left)
|
||||||
facewindow.viewport = msgwindow.viewport
|
facewindow.viewport = msgwindow.viewport
|
||||||
|
|||||||
@@ -88,27 +88,27 @@ class PokeBattle_Move
|
|||||||
baseAcc = pbBaseAccuracy(user,target)
|
baseAcc = pbBaseAccuracy(user,target)
|
||||||
return true if baseAcc==0
|
return true if baseAcc==0
|
||||||
# Calculate all multiplier effects
|
# Calculate all multiplier effects
|
||||||
modifiers = []
|
modifiers = {}
|
||||||
modifiers[BASE_ACC] = baseAcc
|
modifiers[:base_accuracy] = baseAcc
|
||||||
modifiers[ACC_STAGE] = user.stages[PBStats::ACCURACY]
|
modifiers[:accuracy_stage] = user.stages[PBStats::ACCURACY]
|
||||||
modifiers[EVA_STAGE] = target.stages[PBStats::EVASION]
|
modifiers[:evasion_stage] = target.stages[PBStats::EVASION]
|
||||||
modifiers[ACC_MULT] = 1.0
|
modifiers[:accuracy_multiplier] = 1.0
|
||||||
modifiers[EVA_MULT] = 1.0
|
modifiers[:evasion_multiplier] = 1.0
|
||||||
pbCalcAccuracyModifiers(user,target,modifiers)
|
pbCalcAccuracyModifiers(user,target,modifiers)
|
||||||
# Check if move can't miss
|
# Check if move can't miss
|
||||||
return true if modifiers[BASE_ACC]==0
|
return true if modifiers[:base_accuracy] == 0
|
||||||
# Calculation
|
# Calculation
|
||||||
accStage = [[modifiers[ACC_STAGE],-6].max,6].min + 6
|
accStage = [[modifiers[:accuracy_stage], -6].max, 6].min + 6
|
||||||
evaStage = [[modifiers[EVA_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]
|
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]
|
stageDiv = [9,8,7,6,5,4, 3, 3,3,3,3,3,3]
|
||||||
accuracy = 100.0 * stageMul[accStage] / stageDiv[accStage]
|
accuracy = 100.0 * stageMul[accStage] / stageDiv[accStage]
|
||||||
evasion = 100.0 * stageMul[evaStage] / stageDiv[evaStage]
|
evasion = 100.0 * stageMul[evaStage] / stageDiv[evaStage]
|
||||||
accuracy = (accuracy * modifiers[ACC_MULT]).round
|
accuracy = (accuracy * modifiers[:accuracy_multiplier]).round
|
||||||
evasion = (evasion * modifiers[EVA_MULT]).round
|
evasion = (evasion * modifiers[:evasion_multiplier]).round
|
||||||
evasion = 1 if evasion<1
|
evasion = 1 if evasion < 1
|
||||||
# Calculation
|
# Calculation
|
||||||
return @battle.pbRandom(100) < modifiers[BASE_ACC] * accuracy / evasion
|
return @battle.pbRandom(100) < modifiers[:base_accuracy] * accuracy / evasion
|
||||||
end
|
end
|
||||||
|
|
||||||
def pbCalcAccuracyModifiers(user,target,modifiers)
|
def pbCalcAccuracyModifiers(user,target,modifiers)
|
||||||
@@ -135,16 +135,17 @@ class PokeBattle_Move
|
|||||||
BattleHandlers.triggerAccuracyCalcTargetItem(target.item,
|
BattleHandlers.triggerAccuracyCalcTargetItem(target.item,
|
||||||
modifiers,user,target,self,@calcType)
|
modifiers,user,target,self,@calcType)
|
||||||
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
|
||||||
if @battle.field.effects[PBEffects::Gravity]>0
|
# specific values
|
||||||
modifiers[ACC_MULT] *= 5/3.0
|
if @battle.field.effects[PBEffects::Gravity] > 0
|
||||||
|
modifiers[:accuracy_multiplier] *= 5 / 3.0
|
||||||
end
|
end
|
||||||
if user.effects[PBEffects::MicleBerry]
|
if user.effects[PBEffects::MicleBerry]
|
||||||
user.effects[PBEffects::MicleBerry] = false
|
user.effects[PBEffects::MicleBerry] = false
|
||||||
modifiers[ACC_MULT] *= 1.2
|
modifiers[:accuracy_multiplier] *= 1.2
|
||||||
end
|
end
|
||||||
modifiers[EVA_STAGE] = 0 if target.effects[PBEffects::Foresight] && modifiers[EVA_STAGE]>0
|
modifiers[:evasion_stage] = 0 if target.effects[PBEffects::Foresight] && modifiers[:evasion_stage] > 0
|
||||||
modifiers[EVA_STAGE] = 0 if target.effects[PBEffects::MiracleEye] && modifiers[EVA_STAGE]>0
|
modifiers[:evasion_stage] = 0 if target.effects[PBEffects::MiracleEye] && modifiers[:evasion_stage] > 0
|
||||||
end
|
end
|
||||||
|
|
||||||
#=============================================================================
|
#=============================================================================
|
||||||
@@ -241,14 +242,19 @@ class PokeBattle_Move
|
|||||||
defense = (defense.to_f*stageMul[defStage]/stageDiv[defStage]).floor
|
defense = (defense.to_f*stageMul[defStage]/stageDiv[defStage]).floor
|
||||||
end
|
end
|
||||||
# Calculate all multiplier effects
|
# 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)
|
pbCalcDamageMultipliers(user,target,numTargets,type,baseDmg,multipliers)
|
||||||
# Main damage calculation
|
# Main damage calculation
|
||||||
baseDmg = [(baseDmg * multipliers[BASE_DMG_MULT]).round, 1].max
|
baseDmg = [(baseDmg * multipliers[:base_damage_multiplier]).round, 1].max
|
||||||
atk = [(atk * multipliers[ATK_MULT]).round, 1].max
|
atk = [(atk * multipliers[:attack_multiplier]).round, 1].max
|
||||||
defense = [(defense * multipliers[DEF_MULT]).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 = (((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
|
target.damageState.calcDamage = damage
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -257,9 +263,9 @@ class PokeBattle_Move
|
|||||||
if (@battle.pbCheckGlobalAbility(:DARKAURA) && type == :DARK) ||
|
if (@battle.pbCheckGlobalAbility(:DARKAURA) && type == :DARK) ||
|
||||||
(@battle.pbCheckGlobalAbility(:FAIRYAURA) && type == :FAIRY)
|
(@battle.pbCheckGlobalAbility(:FAIRYAURA) && type == :FAIRY)
|
||||||
if @battle.pbCheckGlobalAbility(:AURABREAK)
|
if @battle.pbCheckGlobalAbility(:AURABREAK)
|
||||||
multipliers[BASE_DMG_MULT] *= 2/3.0
|
multipliers[:base_damage_multiplier] *= 2 / 3.0
|
||||||
else
|
else
|
||||||
multipliers[BASE_DMG_MULT] *= 4/3.0
|
multipliers[:base_damage_multiplier] *= 4 / 3.0
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
# Ability effects that alter damage
|
# Ability effects that alter damage
|
||||||
@@ -299,154 +305,154 @@ class PokeBattle_Move
|
|||||||
end
|
end
|
||||||
# Parental Bond's second attack
|
# Parental Bond's second attack
|
||||||
if user.effects[PBEffects::ParentalBond]==1
|
if user.effects[PBEffects::ParentalBond]==1
|
||||||
multipliers[BASE_DMG_MULT] /= 4
|
multipliers[:base_damage_multiplier] /= 4
|
||||||
end
|
end
|
||||||
# Other
|
# Other
|
||||||
if user.effects[PBEffects::MeFirst]
|
if user.effects[PBEffects::MeFirst]
|
||||||
multipliers[BASE_DMG_MULT] *= 1.5
|
multipliers[:base_damage_multiplier] *= 1.5
|
||||||
end
|
end
|
||||||
if user.effects[PBEffects::HelpingHand] && !self.is_a?(PokeBattle_Confusion)
|
if user.effects[PBEffects::HelpingHand] && !self.is_a?(PokeBattle_Confusion)
|
||||||
multipliers[BASE_DMG_MULT] *= 1.5
|
multipliers[:base_damage_multiplier] *= 1.5
|
||||||
end
|
end
|
||||||
if user.effects[PBEffects::Charge]>0 && type == :ELECTRIC
|
if user.effects[PBEffects::Charge]>0 && type == :ELECTRIC
|
||||||
multipliers[BASE_DMG_MULT] *= 2
|
multipliers[:base_damage_multiplier] *= 2
|
||||||
end
|
end
|
||||||
# Mud Sport
|
# Mud Sport
|
||||||
if type == :ELECTRIC
|
if type == :ELECTRIC
|
||||||
@battle.eachBattler do |b|
|
@battle.eachBattler do |b|
|
||||||
next if !b.effects[PBEffects::MudSport]
|
next if !b.effects[PBEffects::MudSport]
|
||||||
multipliers[BASE_DMG_MULT] /= 3
|
multipliers[:base_damage_multiplier] /= 3
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
if @battle.field.effects[PBEffects::MudSportField]>0
|
if @battle.field.effects[PBEffects::MudSportField]>0
|
||||||
multipliers[BASE_DMG_MULT] /= 3
|
multipliers[:base_damage_multiplier] /= 3
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
# Water Sport
|
# Water Sport
|
||||||
if type == :FIRE
|
if type == :FIRE
|
||||||
@battle.eachBattler do |b|
|
@battle.eachBattler do |b|
|
||||||
next if !b.effects[PBEffects::WaterSport]
|
next if !b.effects[PBEffects::WaterSport]
|
||||||
multipliers[BASE_DMG_MULT] /= 3
|
multipliers[:base_damage_multiplier] /= 3
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
if @battle.field.effects[PBEffects::WaterSportField]>0
|
if @battle.field.effects[PBEffects::WaterSportField]>0
|
||||||
multipliers[BASE_DMG_MULT] /= 3
|
multipliers[:base_damage_multiplier] /= 3
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
# Terrain moves
|
# Terrain moves
|
||||||
if user.affectedByTerrain?
|
if user.affectedByTerrain?
|
||||||
case @battle.field.terrain
|
case @battle.field.terrain
|
||||||
when PBBattleTerrains::Electric
|
when PBBattleTerrains::Electric
|
||||||
multipliers[BASE_DMG_MULT] *= 1.5 if type == :ELECTRIC
|
multipliers[:base_damage_multiplier] *= 1.5 if type == :ELECTRIC
|
||||||
when PBBattleTerrains::Grassy
|
when PBBattleTerrains::Grassy
|
||||||
multipliers[BASE_DMG_MULT] *= 1.5 if type == :GRASS
|
multipliers[:base_damage_multiplier] *= 1.5 if type == :GRASS
|
||||||
when PBBattleTerrains::Psychic
|
when PBBattleTerrains::Psychic
|
||||||
multipliers[BASE_DMG_MULT] *= 1.5 if type == :PSYCHIC
|
multipliers[:base_damage_multiplier] *= 1.5 if type == :PSYCHIC
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if @battle.field.terrain==PBBattleTerrains::Misty && target.affectedByTerrain? &&
|
if @battle.field.terrain==PBBattleTerrains::Misty && target.affectedByTerrain? &&
|
||||||
type == :DRAGON
|
type == :DRAGON
|
||||||
multipliers[BASE_DMG_MULT] /= 2
|
multipliers[:base_damage_multiplier] /= 2
|
||||||
end
|
end
|
||||||
# Badge multipliers
|
# Badge multipliers
|
||||||
if @battle.internalBattle
|
if @battle.internalBattle
|
||||||
if user.pbOwnedByPlayer?
|
if user.pbOwnedByPlayer?
|
||||||
if physicalMove? && @battle.pbPlayer.numbadges>=NUM_BADGES_BOOST_ATTACK
|
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
|
elsif specialMove? && @battle.pbPlayer.numbadges >= NUM_BADGES_BOOST_SPATK
|
||||||
multipliers[ATK_MULT] *= 1.1
|
multipliers[:attack_multiplier] *= 1.1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if target.pbOwnedByPlayer?
|
if target.pbOwnedByPlayer?
|
||||||
if physicalMove? && @battle.pbPlayer.numbadges>=NUM_BADGES_BOOST_DEFENSE
|
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
|
elsif specialMove? && @battle.pbPlayer.numbadges >= NUM_BADGES_BOOST_SPDEF
|
||||||
multipliers[DEF_MULT] *= 1.1
|
multipliers[:defense_multiplier] *= 1.1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
# Multi-targeting attacks
|
# Multi-targeting attacks
|
||||||
if numTargets>1
|
if numTargets>1
|
||||||
multipliers[FINAL_DMG_MULT] *= 0.75
|
multipliers[:final_damage_multiplier] *= 0.75
|
||||||
end
|
end
|
||||||
# Weather
|
# Weather
|
||||||
case @battle.pbWeather
|
case @battle.pbWeather
|
||||||
when PBWeather::Sun, PBWeather::HarshSun
|
when PBWeather::Sun, PBWeather::HarshSun
|
||||||
if type == :FIRE
|
if type == :FIRE
|
||||||
multipliers[FINAL_DMG_MULT] *= 1.5
|
multipliers[:final_damage_multiplier] *= 1.5
|
||||||
elsif type == :WATER
|
elsif type == :WATER
|
||||||
multipliers[FINAL_DMG_MULT] /= 2
|
multipliers[:final_damage_multiplier] /= 2
|
||||||
end
|
end
|
||||||
when PBWeather::Rain, PBWeather::HeavyRain
|
when PBWeather::Rain, PBWeather::HeavyRain
|
||||||
if type == :FIRE
|
if type == :FIRE
|
||||||
multipliers[FINAL_DMG_MULT] /= 2
|
multipliers[:final_damage_multiplier] /= 2
|
||||||
elsif type == :WATER
|
elsif type == :WATER
|
||||||
multipliers[FINAL_DMG_MULT] *= 1.5
|
multipliers[:final_damage_multiplier] *= 1.5
|
||||||
end
|
end
|
||||||
when PBWeather::Sandstorm
|
when PBWeather::Sandstorm
|
||||||
if target.pbHasType?(:ROCK) && specialMove? && @function!="122" # Psyshock
|
if target.pbHasType?(:ROCK) && specialMove? && @function != "122" # Psyshock
|
||||||
multipliers[DEF_MULT] *= 1.5
|
multipliers[:defense_multiplier] *= 1.5
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
# Critical hits
|
# Critical hits
|
||||||
if target.damageState.critical
|
if target.damageState.critical
|
||||||
if NEW_CRITICAL_HIT_RATE_MECHANICS
|
if NEW_CRITICAL_HIT_RATE_MECHANICS
|
||||||
multipliers[FINAL_DMG_MULT] *= 1.5
|
multipliers[:final_damage_multiplier] *= 1.5
|
||||||
else
|
else
|
||||||
multipliers[FINAL_DMG_MULT] *= 2
|
multipliers[:final_damage_multiplier] *= 2
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
# Random variance
|
# Random variance
|
||||||
if !self.is_a?(PokeBattle_Confusion)
|
if !self.is_a?(PokeBattle_Confusion)
|
||||||
random = 85+@battle.pbRandom(16)
|
random = 85+@battle.pbRandom(16)
|
||||||
multipliers[FINAL_DMG_MULT] *= random/100.0
|
multipliers[:final_damage_multiplier] *= random / 100.0
|
||||||
end
|
end
|
||||||
# STAB
|
# STAB
|
||||||
if type && user.pbHasType?(type)
|
if type && user.pbHasType?(type)
|
||||||
if user.hasActiveAbility?(:ADAPTABILITY)
|
if user.hasActiveAbility?(:ADAPTABILITY)
|
||||||
multipliers[FINAL_DMG_MULT] *= 2
|
multipliers[:final_damage_multiplier] *= 2
|
||||||
else
|
else
|
||||||
multipliers[FINAL_DMG_MULT] *= 1.5
|
multipliers[:final_damage_multiplier] *= 1.5
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
# Type effectiveness
|
# 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
|
# Burn
|
||||||
if user.status==PBStatuses::BURN && physicalMove? && damageReducedByBurn? &&
|
if user.status==PBStatuses::BURN && physicalMove? && damageReducedByBurn? &&
|
||||||
!user.hasActiveAbility?(:GUTS)
|
!user.hasActiveAbility?(:GUTS)
|
||||||
multipliers[FINAL_DMG_MULT] /= 2
|
multipliers[:final_damage_multiplier] /= 2
|
||||||
end
|
end
|
||||||
# Aurora Veil, Reflect, Light Screen
|
# Aurora Veil, Reflect, Light Screen
|
||||||
if !ignoresReflect? && !target.damageState.critical &&
|
if !ignoresReflect? && !target.damageState.critical &&
|
||||||
!user.hasActiveAbility?(:INFILTRATOR)
|
!user.hasActiveAbility?(:INFILTRATOR)
|
||||||
if target.pbOwnSide.effects[PBEffects::AuroraVeil]>0
|
if target.pbOwnSide.effects[PBEffects::AuroraVeil] > 0
|
||||||
if @battle.pbSideBattlerCount(target)>1
|
if @battle.pbSideBattlerCount(target)>1
|
||||||
multipliers[FINAL_DMG_MULT] *= 2/3.0
|
multipliers[:final_damage_multiplier] *= 2 / 3.0
|
||||||
else
|
else
|
||||||
multipliers[FINAL_DMG_MULT] /= 2
|
multipliers[:final_damage_multiplier] /= 2
|
||||||
end
|
end
|
||||||
elsif target.pbOwnSide.effects[PBEffects::Reflect]>0 && physicalMove?
|
elsif target.pbOwnSide.effects[PBEffects::Reflect] > 0 && physicalMove?
|
||||||
if @battle.pbSideBattlerCount(target)>1
|
if @battle.pbSideBattlerCount(target)>1
|
||||||
multipliers[FINAL_DMG_MULT] *= 2/3.0
|
multipliers[:final_damage_multiplier] *= 2 / 3.0
|
||||||
else
|
else
|
||||||
multipliers[FINAL_DMG_MULT] /= 2
|
multipliers[:final_damage_multiplier] /= 2
|
||||||
end
|
end
|
||||||
elsif target.pbOwnSide.effects[PBEffects::LightScreen]>0 && specialMove?
|
elsif target.pbOwnSide.effects[PBEffects::LightScreen] > 0 && specialMove?
|
||||||
if @battle.pbSideBattlerCount(target)>1
|
if @battle.pbSideBattlerCount(target) > 1
|
||||||
multipliers[FINAL_DMG_MULT] *= 2/3.0
|
multipliers[:final_damage_multiplier] *= 2 / 3.0
|
||||||
else
|
else
|
||||||
multipliers[FINAL_DMG_MULT] /= 2
|
multipliers[:final_damage_multiplier] /= 2
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
# Minimize
|
# Minimize
|
||||||
if target.effects[PBEffects::Minimize] && tramplesMinimize?(2)
|
if target.effects[PBEffects::Minimize] && tramplesMinimize?(2)
|
||||||
multipliers[FINAL_DMG_MULT] *= 2
|
multipliers[:final_damage_multiplier] *= 2
|
||||||
end
|
end
|
||||||
# Move-specific base damage modifiers
|
# 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
|
# 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
|
end
|
||||||
|
|
||||||
#=============================================================================
|
#=============================================================================
|
||||||
|
|||||||
@@ -1035,7 +1035,7 @@ end
|
|||||||
class PokeBattle_Move_0A9 < PokeBattle_Move
|
class PokeBattle_Move_0A9 < PokeBattle_Move
|
||||||
def pbCalcAccuracyMultipliers(user,target,multipliers)
|
def pbCalcAccuracyMultipliers(user,target,multipliers)
|
||||||
super
|
super
|
||||||
modifiers[EVA_STAGE] = 0 # Accuracy stat stage
|
modifiers[:evasion_stage] = 0
|
||||||
end
|
end
|
||||||
|
|
||||||
def pbGetDefenseStats(user,target)
|
def pbGetDefenseStats(user,target)
|
||||||
|
|||||||
@@ -274,7 +274,12 @@ class PokeBattle_AI
|
|||||||
defense = pbRoughStat(target,PBStats::SPDEF,skill)
|
defense = pbRoughStat(target,PBStats::SPDEF,skill)
|
||||||
end
|
end
|
||||||
##### Calculate all multiplier effects #####
|
##### 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
|
# Ability effects that alter damage
|
||||||
moldBreaker = false
|
moldBreaker = false
|
||||||
if skill>=PBTrainerAI.highSkill && target.hasMoldBreaker?
|
if skill>=PBTrainerAI.highSkill && target.hasMoldBreaker?
|
||||||
@@ -349,15 +354,15 @@ class PokeBattle_AI
|
|||||||
if (@battle.pbCheckGlobalAbility(:DARKAURA) && type == :DARK) ||
|
if (@battle.pbCheckGlobalAbility(:DARKAURA) && type == :DARK) ||
|
||||||
(@battle.pbCheckGlobalAbility(:FAIRYAURA) && type == :FAIRY)
|
(@battle.pbCheckGlobalAbility(:FAIRYAURA) && type == :FAIRY)
|
||||||
if @battle.pbCheckGlobalAbility(:AURABREAK)
|
if @battle.pbCheckGlobalAbility(:AURABREAK)
|
||||||
multipliers[BASE_DMG_MULT] *= 2/3
|
multipliers[:base_damage_multiplier] *= 2 / 3.0
|
||||||
else
|
else
|
||||||
multipliers[BASE_DMG_MULT] *= 4/3
|
multipliers[:base_damage_multiplier] *= 4 / 3.0
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
# Parental Bond
|
# Parental Bond
|
||||||
if skill>=PBTrainerAI.mediumSkill && user.hasActiveAbility?(:PARENTALBOND)
|
if skill>=PBTrainerAI.mediumSkill && user.hasActiveAbility?(:PARENTALBOND)
|
||||||
multipliers[BASE_DMG_MULT] *= 1.25
|
multipliers[:base_damage_multiplier] *= 1.25
|
||||||
end
|
end
|
||||||
# Me First
|
# Me First
|
||||||
# TODO
|
# TODO
|
||||||
@@ -365,7 +370,7 @@ class PokeBattle_AI
|
|||||||
# Charge
|
# Charge
|
||||||
if skill>=PBTrainerAI.mediumSkill
|
if skill>=PBTrainerAI.mediumSkill
|
||||||
if user.effects[PBEffects::Charge]>0 && type == :ELECTRIC
|
if user.effects[PBEffects::Charge]>0 && type == :ELECTRIC
|
||||||
multipliers[BASE_DMG_MULT] *= 2
|
multipliers[:base_damage_multiplier] *= 2
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
# Mud Sport and Water Sport
|
# Mud Sport and Water Sport
|
||||||
@@ -373,21 +378,21 @@ class PokeBattle_AI
|
|||||||
if type == :ELECTRIC
|
if type == :ELECTRIC
|
||||||
@battle.eachBattler do |b|
|
@battle.eachBattler do |b|
|
||||||
next if !b.effects[PBEffects::MudSport]
|
next if !b.effects[PBEffects::MudSport]
|
||||||
multipliers[BASE_DMG_MULT] /= 3
|
multipliers[:base_damage_multiplier] /= 3
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
if @battle.field.effects[PBEffects::MudSportField]>0
|
if @battle.field.effects[PBEffects::MudSportField]>0
|
||||||
multipliers[BASE_DMG_MULT] /= 3
|
multipliers[:base_damage_multiplier] /= 3
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if type == :FIRE
|
if type == :FIRE
|
||||||
@battle.eachBattler do |b|
|
@battle.eachBattler do |b|
|
||||||
next if !b.effects[PBEffects::WaterSport]
|
next if !b.effects[PBEffects::WaterSport]
|
||||||
multipliers[BASE_DMG_MULT] /= 3
|
multipliers[:base_damage_multiplier] /= 3
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
if @battle.field.effects[PBEffects::WaterSportField]>0
|
if @battle.field.effects[PBEffects::WaterSportField]>0
|
||||||
multipliers[BASE_DMG_MULT] /= 3
|
multipliers[:base_damage_multiplier] /= 3
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -395,16 +400,16 @@ class PokeBattle_AI
|
|||||||
if user.affectedByTerrain? && skill>=PBTrainerAI.mediumSkill
|
if user.affectedByTerrain? && skill>=PBTrainerAI.mediumSkill
|
||||||
case @battle.field.terrain
|
case @battle.field.terrain
|
||||||
when PBBattleTerrains::Electric
|
when PBBattleTerrains::Electric
|
||||||
multipliers[BASE_DMG_MULT] *= 1.5 if type == :ELECTRIC
|
multipliers[:base_damage_multiplier] *= 1.5 if type == :ELECTRIC
|
||||||
when PBBattleTerrains::Grassy
|
when PBBattleTerrains::Grassy
|
||||||
multipliers[BASE_DMG_MULT] *= 1.5 if type == :GRASS
|
multipliers[:base_damage_multiplier] *= 1.5 if type == :GRASS
|
||||||
when PBBattleTerrains::Psychic
|
when PBBattleTerrains::Psychic
|
||||||
multipliers[BASE_DMG_MULT] *= 1.5 if type == :PSYCHIC
|
multipliers[:base_damage_multiplier] *= 1.5 if type == :PSYCHIC
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if target.affectedByTerrain? && skill>=PBTrainerAI.mediumSkill
|
if target.affectedByTerrain? && skill>=PBTrainerAI.mediumSkill
|
||||||
if @battle.field.terrain==PBBattleTerrains::Misty && type == :DRAGON
|
if @battle.field.terrain==PBBattleTerrains::Misty && type == :DRAGON
|
||||||
multipliers[BASE_DMG_MULT] /= 2
|
multipliers[:base_damage_multiplier] /= 2
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
# Badge multipliers
|
# Badge multipliers
|
||||||
@@ -413,10 +418,10 @@ class PokeBattle_AI
|
|||||||
# Don't need to check the Atk/Sp Atk-boosting badges because the AI
|
# Don't need to check the Atk/Sp Atk-boosting badges because the AI
|
||||||
# won't control the player's Pokémon.
|
# won't control the player's Pokémon.
|
||||||
if target.pbOwnedByPlayer?
|
if target.pbOwnedByPlayer?
|
||||||
if move.physicalMove?(type) && @battle.pbPlayer.numbadges>=NUM_BADGES_BOOST_DEFENSE
|
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
|
elsif move.specialMove?(type) && @battle.pbPlayer.numbadges >= NUM_BADGES_BOOST_SPDEF
|
||||||
multipliers[DEF_MULT] *= 1.1
|
multipliers[:defense_multiplier] *= 1.1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -424,7 +429,7 @@ class PokeBattle_AI
|
|||||||
# Multi-targeting attacks
|
# Multi-targeting attacks
|
||||||
if skill>=PBTrainerAI.highSkill
|
if skill>=PBTrainerAI.highSkill
|
||||||
if pbTargetsMultiple?(move,user)
|
if pbTargetsMultiple?(move,user)
|
||||||
multipliers[FINAL_DMG_MULT] *= 0.75
|
multipliers[:final_damage_multiplier] *= 0.75
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
# Weather
|
# Weather
|
||||||
@@ -432,19 +437,19 @@ class PokeBattle_AI
|
|||||||
case @battle.pbWeather
|
case @battle.pbWeather
|
||||||
when PBWeather::Sun, PBWeather::HarshSun
|
when PBWeather::Sun, PBWeather::HarshSun
|
||||||
if type == :FIRE
|
if type == :FIRE
|
||||||
multipliers[FINAL_DMG_MULT] *= 1.5
|
multipliers[:final_damage_multiplier] *= 1.5
|
||||||
elsif type == :WATER
|
elsif type == :WATER
|
||||||
multipliers[FINAL_DMG_MULT] /= 2
|
multipliers[:final_damage_multiplier] /= 2
|
||||||
end
|
end
|
||||||
when PBWeather::Rain, PBWeather::HeavyRain
|
when PBWeather::Rain, PBWeather::HeavyRain
|
||||||
if type == :FIRE
|
if type == :FIRE
|
||||||
multipliers[FINAL_DMG_MULT] /= 2
|
multipliers[:final_damage_multiplier] /= 2
|
||||||
elsif type == :WATER
|
elsif type == :WATER
|
||||||
multipliers[FINAL_DMG_MULT] *= 1.5
|
multipliers[:final_damage_multiplier] *= 1.5
|
||||||
end
|
end
|
||||||
when PBWeather::Sandstorm
|
when PBWeather::Sandstorm
|
||||||
if target.pbHasType?(:ROCK) && move.specialMove?(type) && move.function!="122" # Psyshock
|
if target.pbHasType?(:ROCK) && move.specialMove?(type) && move.function != "122" # Psyshock
|
||||||
multipliers[DEF_MULT] *= 1.5
|
multipliers[:defense_multiplier] *= 1.5
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -454,45 +459,45 @@ class PokeBattle_AI
|
|||||||
if skill>=PBTrainerAI.mediumSkill
|
if skill>=PBTrainerAI.mediumSkill
|
||||||
if type && user.pbHasType?(type)
|
if type && user.pbHasType?(type)
|
||||||
if user.hasActiveAbility?(:ADAPTABILITY)
|
if user.hasActiveAbility?(:ADAPTABILITY)
|
||||||
multipliers[FINAL_DMG_MULT] *= 2
|
multipliers[:final_damage_multiplier] *= 2
|
||||||
else
|
else
|
||||||
multipliers[FINAL_DMG_MULT] *= 1.5
|
multipliers[:final_damage_multiplier] *= 1.5
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
# Type effectiveness
|
# Type effectiveness
|
||||||
if skill>=PBTrainerAI.mediumSkill
|
if skill>=PBTrainerAI.mediumSkill
|
||||||
typemod = pbCalcTypeMod(type,user,target)
|
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
|
end
|
||||||
# Burn
|
# Burn
|
||||||
if skill>=PBTrainerAI.highSkill
|
if skill>=PBTrainerAI.highSkill
|
||||||
if user.status==PBStatuses::BURN && move.physicalMove?(type) &&
|
if user.status==PBStatuses::BURN && move.physicalMove?(type) &&
|
||||||
!user.hasActiveAbility?(:GUTS) &&
|
!user.hasActiveAbility?(:GUTS) &&
|
||||||
!(MECHANICS_GENERATION >= 6 && move.function == "07E") # Facade
|
!(MECHANICS_GENERATION >= 6 && move.function == "07E") # Facade
|
||||||
multipliers[FINAL_DMG_MULT] /= 2
|
multipliers[:final_damage_multiplier] /= 2
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
# Aurora Veil, Reflect, Light Screen
|
# Aurora Veil, Reflect, Light Screen
|
||||||
if skill>=PBTrainerAI.highSkill
|
if skill>=PBTrainerAI.highSkill
|
||||||
if !move.ignoresReflect? && !user.hasActiveAbility?(:INFILTRATOR)
|
if !move.ignoresReflect? && !user.hasActiveAbility?(:INFILTRATOR)
|
||||||
if target.pbOwnSide.effects[PBEffects::AuroraVeil]>0
|
if target.pbOwnSide.effects[PBEffects::AuroraVeil] > 0
|
||||||
if @battle.pbSideBattlerCount(target)>1
|
if @battle.pbSideBattlerCount(target) > 1
|
||||||
multipliers[FINAL_DMG_MULT] *= 2/3.0
|
multipliers[:final_damage_multiplier] *= 2 / 3.0
|
||||||
else
|
else
|
||||||
multipliers[FINAL_DMG_MULT] /= 2
|
multipliers[:final_damage_multiplier] /= 2
|
||||||
end
|
end
|
||||||
elsif target.pbOwnSide.effects[PBEffects::Reflect]>0 && move.physicalMove?(type)
|
elsif target.pbOwnSide.effects[PBEffects::Reflect] > 0 && move.physicalMove?(type)
|
||||||
if @battle.pbSideBattlerCount(target)>1
|
if @battle.pbSideBattlerCount(target) > 1
|
||||||
multipliers[FINAL_DMG_MULT] *= 2/3.0
|
multipliers[:final_damage_multiplier] *= 2 / 3.0
|
||||||
else
|
else
|
||||||
multipliers[FINAL_DMG_MULT] /= 2
|
multipliers[:final_damage_multiplier] /= 2
|
||||||
end
|
end
|
||||||
elsif target.pbOwnSide.effects[PBEffects::LightScreen]>0 && move.specialMove?(type)
|
elsif target.pbOwnSide.effects[PBEffects::LightScreen] > 0 && move.specialMove?(type)
|
||||||
if @battle.pbSideBattlerCount(target)>1
|
if @battle.pbSideBattlerCount(target) > 1
|
||||||
multipliers[FINAL_DMG_MULT] *= 2/3.0
|
multipliers[:final_damage_multiplier] *= 2 / 3.0
|
||||||
else
|
else
|
||||||
multipliers[FINAL_DMG_MULT] /= 2
|
multipliers[:final_damage_multiplier] /= 2
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -500,7 +505,7 @@ class PokeBattle_AI
|
|||||||
# Minimize
|
# Minimize
|
||||||
if skill>=PBTrainerAI.highSkill
|
if skill>=PBTrainerAI.highSkill
|
||||||
if target.effects[PBEffects::Minimize] && move.tramplesMinimize?(2)
|
if target.effects[PBEffects::Minimize] && move.tramplesMinimize?(2)
|
||||||
multipliers[FINAL_DMG_MULT] *= 2
|
multipliers[:final_damage_multiplier] *= 2
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
# Move-specific base damage modifiers
|
# Move-specific base damage modifiers
|
||||||
@@ -508,11 +513,11 @@ class PokeBattle_AI
|
|||||||
# Move-specific final damage modifiers
|
# Move-specific final damage modifiers
|
||||||
# TODO
|
# TODO
|
||||||
##### Main damage calculation #####
|
##### Main damage calculation #####
|
||||||
baseDmg = [(baseDmg * multipliers[BASE_DMG_MULT]).round, 1].max
|
baseDmg = [(baseDmg * multipliers[:base_damage_multiplier]).round, 1].max
|
||||||
atk = [(atk * multipliers[ATK_MULT]).round, 1].max
|
atk = [(atk * multipliers[:attack_multiplier]).round, 1].max
|
||||||
defense = [(defense * multipliers[DEF_MULT]).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 = (((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"
|
# "AI-specific calculations below"
|
||||||
# Increased critical hit rates
|
# Increased critical hit rates
|
||||||
if skill>=PBTrainerAI.mediumSkill
|
if skill>=PBTrainerAI.mediumSkill
|
||||||
@@ -567,26 +572,26 @@ class PokeBattle_AI
|
|||||||
# Get the move's type
|
# Get the move's type
|
||||||
type = pbRoughType(move,user,skill)
|
type = pbRoughType(move,user,skill)
|
||||||
# Calculate all modifier effects
|
# Calculate all modifier effects
|
||||||
modifiers = []
|
modifiers = {}
|
||||||
modifiers[BASE_ACC] = baseAcc
|
modifiers[:base_accuracy] = baseAcc
|
||||||
modifiers[ACC_STAGE] = user.stages[PBStats::ACCURACY]
|
modifiers[:accuracy_stage] = user.stages[PBStats::ACCURACY]
|
||||||
modifiers[EVA_STAGE] = target.stages[PBStats::EVASION]
|
modifiers[:evasion_stage] = target.stages[PBStats::EVASION]
|
||||||
modifiers[ACC_MULT] = 1.0
|
modifiers[:accuracy_multiplier] = 1.0
|
||||||
modifiers[EVA_MULT] = 1.0
|
modifiers[:evasion_multiplier] = 1.0
|
||||||
pbCalcAccuracyModifiers(user,target,modifiers,move,type,skill)
|
pbCalcAccuracyModifiers(user,target,modifiers,move,type,skill)
|
||||||
# Check if move can't miss
|
# Check if move can't miss
|
||||||
return 125 if modifiers[BASE_ACC]==0
|
return 125 if modifiers[:base_accuracy]==0
|
||||||
# Calculation
|
# Calculation
|
||||||
accStage = [[modifiers[ACC_STAGE],-6].max,6].min + 6
|
accStage = [[modifiers[:accuracy_stage], -6].max, 6].min + 6
|
||||||
evaStage = [[modifiers[EVA_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]
|
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]
|
stageDiv = [9,8,7,6,5,4, 3, 3,3,3,3,3,3]
|
||||||
accuracy = 100.0 * stageMul[accStage] / stageDiv[accStage]
|
accuracy = 100.0 * stageMul[accStage] / stageDiv[accStage]
|
||||||
evasion = 100.0 * stageMul[evaStage] / stageDiv[evaStage]
|
evasion = 100.0 * stageMul[evaStage] / stageDiv[evaStage]
|
||||||
accuracy = (accuracy * modifiers[ACC_MULT]).round
|
accuracy = (accuracy * modifiers[:accuracy_multiplier]).round
|
||||||
evasion = (evasion * modifiers[EVA_MULT]).round
|
evasion = (evasion * modifiers[:evasion_multiplier]).round
|
||||||
evasion = 1 if evasion<1
|
evasion = 1 if evasion<1
|
||||||
return modifiers[BASE_ACC] * accuracy / evasion
|
return modifiers[:base_accuracy] * accuracy / evasion
|
||||||
end
|
end
|
||||||
|
|
||||||
def pbCalcAccuracyModifiers(user,target,modifiers,move,type,skill)
|
def pbCalcAccuracyModifiers(user,target,modifiers,move,type,skill)
|
||||||
@@ -625,35 +630,35 @@ class PokeBattle_AI
|
|||||||
modifiers,user,target,move,type)
|
modifiers,user,target,move,type)
|
||||||
end
|
end
|
||||||
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 skill>=PBTrainerAI.mediumSkill
|
||||||
if @battle.field.effects[PBEffects::Gravity]>0
|
if @battle.field.effects[PBEffects::Gravity] > 0
|
||||||
modifiers[ACC_MULT] *= 5/3.0
|
modifiers[:accuracy_multiplier] *= 5/3.0
|
||||||
end
|
end
|
||||||
if user.effects[PBEffects::MicleBerry]
|
if user.effects[PBEffects::MicleBerry]
|
||||||
modifiers[ACC_MULT] *= 1.2
|
modifiers[:accuracy_multiplier] *= 1.2
|
||||||
end
|
end
|
||||||
modifiers[EVA_STAGE] = 0 if target.effects[PBEffects::Foresight] && modifiers[EVA_STAGE]>0
|
modifiers[:evasion_stage] = 0 if target.effects[PBEffects::Foresight] && modifiers[:evasion_stage] > 0
|
||||||
modifiers[EVA_STAGE] = 0 if target.effects[PBEffects::MiracleEye] && modifiers[EVA_STAGE]>0
|
modifiers[:evasion_stage] = 0 if target.effects[PBEffects::MiracleEye] && modifiers[:evasion_stage] > 0
|
||||||
end
|
end
|
||||||
# "AI-specific calculations below"
|
# "AI-specific calculations below"
|
||||||
if skill>=PBTrainerAI.mediumSkill
|
if skill>=PBTrainerAI.mediumSkill
|
||||||
modifiers[EVA_STAGE] = 0 if move.function=="0A9" # Chip Away
|
modifiers[:evasion_stage] = 0 if move.function == "0A9" # Chip Away
|
||||||
modifiers[BASE_ACC] = 0 if ["0A5","139","13A","13B","13C", # "Always hit"
|
modifiers[:base_accuracy] = 0 if ["0A5", "139", "13A", "13B", "13C", # "Always hit"
|
||||||
"147"].include?(move.function)
|
"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
|
user.effects[PBEffects::LockOnPos]==target.index
|
||||||
end
|
end
|
||||||
if skill>=PBTrainerAI.highSkill
|
if skill>=PBTrainerAI.highSkill
|
||||||
if move.function=="006" # Toxic
|
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)
|
user.pbHasType?(:POISON)
|
||||||
end
|
end
|
||||||
if move.function=="070" # OHKO moves
|
if move.function=="070" # OHKO moves
|
||||||
modifiers[BASE_ACC] = move.accuracy+user.level-target.level
|
modifiers[:base_accuracy] = move.accuracy + user.level - target.level
|
||||||
modifiers[ACC_MULT] = 0 if target.level>user.level
|
modifiers[:accuracy_multiplier] = 0 if target.level > user.level
|
||||||
if skill>=PBTrainerAI.bestSkill
|
if skill>=PBTrainerAI.bestSkill
|
||||||
modifiers[ACC_MULT] = 0 if target.hasActiveAbility?(:STURDY)
|
modifiers[:accuracy_multiplier] = 0 if target.hasActiveAbility?(:STURDY)
|
||||||
end
|
end
|
||||||
end
|
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)
|
def pbBattleConfusionBerry(battler,battle,item,forced,flavor,confuseMsg)
|
||||||
return false if !forced && !battler.canHeal?
|
return false if !forced && !battler.canHeal?
|
||||||
return false if !forced && !battler.canConsumePinchBerry?(MECHANICS_GENERATION >= 7)
|
return false if !forced && !battler.canConsumePinchBerry?(MECHANICS_GENERATION >= 7)
|
||||||
@@ -582,16 +571,16 @@ def pbBattleGem(user,type,move,mults,moveType)
|
|||||||
return if moveType != type
|
return if moveType != type
|
||||||
user.effects[PBEffects::GemConsumed] = user.item_id
|
user.effects[PBEffects::GemConsumed] = user.item_id
|
||||||
if MECHANICS_GENERATION >= 6
|
if MECHANICS_GENERATION >= 6
|
||||||
mults[BASE_DMG_MULT] *= 1.3
|
mults[:base_damage_multiplier] *= 1.3
|
||||||
else
|
else
|
||||||
mults[BASE_DMG_MULT] *= 1.5
|
mults[:base_damage_multiplier] *= 1.5
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def pbBattleTypeWeakingBerry(type,moveType,target,mults)
|
def pbBattleTypeWeakingBerry(type,moveType,target,mults)
|
||||||
return if moveType != type
|
return if moveType != type
|
||||||
return if PBTypeEffectiveness.resistant?(target.damageState.typeMod) && moveType != :NORMAL
|
return if PBTypeEffectiveness.resistant?(target.damageState.typeMod) && moveType != :NORMAL
|
||||||
mults[FINAL_DMG_MULT] /= 2
|
mults[:final_damage_multiplier] /= 2
|
||||||
target.damageState.berryWeakened = true
|
target.damageState.berryWeakened = true
|
||||||
target.battle.pbCommonAnimation("EatBerry",target)
|
target.battle.pbCommonAnimation("EatBerry",target)
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -768,37 +768,37 @@ BattleHandlers::MoveBaseTypeModifierAbility.add(:REFRIGERATE,
|
|||||||
|
|
||||||
BattleHandlers::AccuracyCalcUserAbility.add(:COMPOUNDEYES,
|
BattleHandlers::AccuracyCalcUserAbility.add(:COMPOUNDEYES,
|
||||||
proc { |ability,mods,user,target,move,type|
|
proc { |ability,mods,user,target,move,type|
|
||||||
mods[ACC_MULT] *= 1.3
|
mods[:accuracy_multiplier] *= 1.3
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
BattleHandlers::AccuracyCalcUserAbility.add(:HUSTLE,
|
BattleHandlers::AccuracyCalcUserAbility.add(:HUSTLE,
|
||||||
proc { |ability,mods,user,target,move,type|
|
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,
|
BattleHandlers::AccuracyCalcUserAbility.add(:KEENEYE,
|
||||||
proc { |ability,mods,user,target,move,type|
|
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,
|
BattleHandlers::AccuracyCalcUserAbility.add(:NOGUARD,
|
||||||
proc { |ability,mods,user,target,move,type|
|
proc { |ability,mods,user,target,move,type|
|
||||||
mods[BASE_ACC] = 0
|
mods[:base_accuracy] = 0
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
BattleHandlers::AccuracyCalcUserAbility.add(:UNAWARE,
|
BattleHandlers::AccuracyCalcUserAbility.add(:UNAWARE,
|
||||||
proc { |ability,mods,user,target,move,type|
|
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,
|
BattleHandlers::AccuracyCalcUserAbility.add(:VICTORYSTAR,
|
||||||
proc { |ability,mods,user,target,move,type|
|
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,
|
BattleHandlers::AccuracyCalcUserAllyAbility.add(:VICTORYSTAR,
|
||||||
proc { |ability,mods,user,target,move,type|
|
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,
|
BattleHandlers::AccuracyCalcTargetAbility.add(:LIGHTNINGROD,
|
||||||
proc { |ability,mods,user,target,move,type|
|
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,
|
BattleHandlers::AccuracyCalcTargetAbility.add(:NOGUARD,
|
||||||
proc { |ability,mods,user,target,move,type|
|
proc { |ability,mods,user,target,move,type|
|
||||||
mods[BASE_ACC] = 0
|
mods[:base_accuracy] = 0
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
BattleHandlers::AccuracyCalcTargetAbility.add(:SANDVEIL,
|
BattleHandlers::AccuracyCalcTargetAbility.add(:SANDVEIL,
|
||||||
proc { |ability,mods,user,target,move,type|
|
proc { |ability,mods,user,target,move,type|
|
||||||
if target.battle.pbWeather==PBWeather::Sandstorm
|
if target.battle.pbWeather==PBWeather::Sandstorm
|
||||||
mods[EVA_MULT] *= 1.25
|
mods[:evasion_multiplier] *= 1.25
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@@ -839,33 +839,33 @@ BattleHandlers::AccuracyCalcTargetAbility.add(:SANDVEIL,
|
|||||||
BattleHandlers::AccuracyCalcTargetAbility.add(:SNOWCLOAK,
|
BattleHandlers::AccuracyCalcTargetAbility.add(:SNOWCLOAK,
|
||||||
proc { |ability,mods,user,target,move,type|
|
proc { |ability,mods,user,target,move,type|
|
||||||
if target.battle.pbWeather==PBWeather::Hail
|
if target.battle.pbWeather==PBWeather::Hail
|
||||||
mods[EVA_MULT] *= 1.25
|
mods[:evasion_multiplier] *= 1.25
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
BattleHandlers::AccuracyCalcTargetAbility.add(:STORMDRAIN,
|
BattleHandlers::AccuracyCalcTargetAbility.add(:STORMDRAIN,
|
||||||
proc { |ability,mods,user,target,move,type|
|
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,
|
BattleHandlers::AccuracyCalcTargetAbility.add(:TANGLEDFEET,
|
||||||
proc { |ability,mods,user,target,move,type|
|
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,
|
BattleHandlers::AccuracyCalcTargetAbility.add(:UNAWARE,
|
||||||
proc { |ability,mods,user,target,move,type|
|
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,
|
BattleHandlers::AccuracyCalcTargetAbility.add(:WONDERSKIN,
|
||||||
proc { |ability,mods,user,target,move,type|
|
proc { |ability,mods,user,target,move,type|
|
||||||
if move.statusMove? && user.opposes?(target)
|
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
|
end
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@@ -876,7 +876,7 @@ BattleHandlers::AccuracyCalcTargetAbility.add(:WONDERSKIN,
|
|||||||
|
|
||||||
BattleHandlers::DamageCalcUserAbility.add(:AERILATE,
|
BattleHandlers::DamageCalcUserAbility.add(:AERILATE,
|
||||||
proc { |ability,user,target,move,mults,baseDmg,type|
|
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,29 +887,29 @@ BattleHandlers::DamageCalcUserAbility.add(:ANALYTIC,
|
|||||||
if (target.battle.choices[target.index][0]!=:UseMove &&
|
if (target.battle.choices[target.index][0]!=:UseMove &&
|
||||||
target.battle.choices[target.index][0]!=:Shift) ||
|
target.battle.choices[target.index][0]!=:Shift) ||
|
||||||
target.movedThisRound?
|
target.movedThisRound?
|
||||||
mults[BASE_DMG_MULT] *= 1.3
|
mults[:base_damage_multiplier] *= 1.3
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
BattleHandlers::DamageCalcUserAbility.add(:BLAZE,
|
BattleHandlers::DamageCalcUserAbility.add(:BLAZE,
|
||||||
proc { |ability,user,target,move,mults,baseDmg,type|
|
proc { |ability,user,target,move,mults,baseDmg,type|
|
||||||
if user.hp<=user.totalhp/3 && type == :FIRE
|
if user.hp <= user.totalhp / 3 && type == :FIRE
|
||||||
mults[ATK_MULT] *= 1.5
|
mults[:attack_multiplier] *= 1.5
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
BattleHandlers::DamageCalcUserAbility.add(:DEFEATIST,
|
BattleHandlers::DamageCalcUserAbility.add(:DEFEATIST,
|
||||||
proc { |ability,user,target,move,mults,baseDmg,type|
|
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,
|
BattleHandlers::DamageCalcUserAbility.add(:FLAREBOOST,
|
||||||
proc { |ability,user,target,move,mults,baseDmg,type|
|
proc { |ability,user,target,move,mults,baseDmg,type|
|
||||||
if user.burned? && move.specialMove?
|
if user.burned? && move.specialMove?
|
||||||
mults[BASE_DMG_MULT] *= 1.5
|
mults[:base_damage_multiplier] *= 1.5
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@@ -917,7 +917,7 @@ BattleHandlers::DamageCalcUserAbility.add(:FLAREBOOST,
|
|||||||
BattleHandlers::DamageCalcUserAbility.add(:FLASHFIRE,
|
BattleHandlers::DamageCalcUserAbility.add(:FLASHFIRE,
|
||||||
proc { |ability,user,target,move,mults,baseDmg,type|
|
proc { |ability,user,target,move,mults,baseDmg,type|
|
||||||
if user.effects[PBEffects::FlashFire] && type == :FIRE
|
if user.effects[PBEffects::FlashFire] && type == :FIRE
|
||||||
mults[ATK_MULT] *= 1.5
|
mults[:attack_multiplier] *= 1.5
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@@ -926,7 +926,7 @@ BattleHandlers::DamageCalcUserAbility.add(:FLOWERGIFT,
|
|||||||
proc { |ability,user,target,move,mults,baseDmg,type|
|
proc { |ability,user,target,move,mults,baseDmg,type|
|
||||||
w = user.battle.pbWeather
|
w = user.battle.pbWeather
|
||||||
if move.physicalMove? && (w==PBWeather::Sun || w==PBWeather::HarshSun)
|
if move.physicalMove? && (w==PBWeather::Sun || w==PBWeather::HarshSun)
|
||||||
mults[ATK_MULT] *= 1.5
|
mults[:attack_multiplier] *= 1.5
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@@ -934,14 +934,14 @@ BattleHandlers::DamageCalcUserAbility.add(:FLOWERGIFT,
|
|||||||
BattleHandlers::DamageCalcUserAbility.add(:GUTS,
|
BattleHandlers::DamageCalcUserAbility.add(:GUTS,
|
||||||
proc { |ability,user,target,move,mults,baseDmg,type|
|
proc { |ability,user,target,move,mults,baseDmg,type|
|
||||||
if user.pbHasAnyStatus? && move.physicalMove?
|
if user.pbHasAnyStatus? && move.physicalMove?
|
||||||
mults[ATK_MULT] *= 1.5
|
mults[:attack_multiplier] *= 1.5
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
BattleHandlers::DamageCalcUserAbility.add(:HUGEPOWER,
|
BattleHandlers::DamageCalcUserAbility.add(:HUGEPOWER,
|
||||||
proc { |ability,user,target,move,mults,baseDmg,type|
|
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,
|
BattleHandlers::DamageCalcUserAbility.add(:HUSTLE,
|
||||||
proc { |ability,user,target,move,mults,baseDmg,type|
|
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,
|
BattleHandlers::DamageCalcUserAbility.add(:IRONFIST,
|
||||||
proc { |ability,user,target,move,mults,baseDmg,type|
|
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,
|
BattleHandlers::DamageCalcUserAbility.add(:MEGALAUNCHER,
|
||||||
proc { |ability,user,target,move,mults,baseDmg,type|
|
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?
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -969,8 +969,8 @@ BattleHandlers::DamageCalcUserAbility.add(:MINUS,
|
|||||||
proc { |ability,user,target,move,mults,baseDmg,type|
|
proc { |ability,user,target,move,mults,baseDmg,type|
|
||||||
next if !move.specialMove?
|
next if !move.specialMove?
|
||||||
user.eachAlly do |b|
|
user.eachAlly do |b|
|
||||||
next if !b.hasActiveAbility?([:MINUS,:PLUS])
|
next if !b.hasActiveAbility?([:MINUS, :PLUS])
|
||||||
mults[ATK_MULT] *= 1.5
|
mults[:attack_multiplier] *= 1.5
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
@@ -981,22 +981,22 @@ BattleHandlers::DamageCalcUserAbility.copy(:MINUS,:PLUS)
|
|||||||
BattleHandlers::DamageCalcUserAbility.add(:NEUROFORCE,
|
BattleHandlers::DamageCalcUserAbility.add(:NEUROFORCE,
|
||||||
proc { |ability,user,target,move,mults,baseDmg,type|
|
proc { |ability,user,target,move,mults,baseDmg,type|
|
||||||
if PBTypeEffectiveness.superEffective?(target.damageState.typeMod)
|
if PBTypeEffectiveness.superEffective?(target.damageState.typeMod)
|
||||||
mults[FINAL_DMG_MULT] *= 1.25
|
mults[:final_damage_multiplier] *= 1.25
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
BattleHandlers::DamageCalcUserAbility.add(:OVERGROW,
|
BattleHandlers::DamageCalcUserAbility.add(:OVERGROW,
|
||||||
proc { |ability,user,target,move,mults,baseDmg,type|
|
proc { |ability,user,target,move,mults,baseDmg,type|
|
||||||
if user.hp<=user.totalhp/3 && type == :GRASS
|
if user.hp <= user.totalhp / 3 && type == :GRASS
|
||||||
mults[ATK_MULT] *= 1.5
|
mults[:attack_multiplier] *= 1.5
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
BattleHandlers::DamageCalcUserAbility.add(:RECKLESS,
|
BattleHandlers::DamageCalcUserAbility.add(:RECKLESS,
|
||||||
proc { |ability,user,target,move,mults,baseDmg,type|
|
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|
|
proc { |ability,user,target,move,mults,baseDmg,type|
|
||||||
if user.gender!=2 && target.gender!=2
|
if user.gender!=2 && target.gender!=2
|
||||||
if user.gender==target.gender
|
if user.gender==target.gender
|
||||||
mults[BASE_DMG_MULT] *= 1.25
|
mults[:base_damage_multiplier] *= 1.25
|
||||||
else
|
else
|
||||||
mults[BASE_DMG_MULT] *= 0.75
|
mults[:base_damage_multiplier] *= 0.75
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
@@ -1016,28 +1016,28 @@ BattleHandlers::DamageCalcUserAbility.add(:SANDFORCE,
|
|||||||
proc { |ability,user,target,move,mults,baseDmg,type|
|
proc { |ability,user,target,move,mults,baseDmg,type|
|
||||||
if user.battle.pbWeather==PBWeather::Sandstorm &&
|
if user.battle.pbWeather==PBWeather::Sandstorm &&
|
||||||
[:ROCK, :GROUND, :STEEL].include?(type)
|
[:ROCK, :GROUND, :STEEL].include?(type)
|
||||||
mults[BASE_DMG_MULT] *= 1.3
|
mults[:base_damage_multiplier] *= 1.3
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
BattleHandlers::DamageCalcUserAbility.add(:SHEERFORCE,
|
BattleHandlers::DamageCalcUserAbility.add(:SHEERFORCE,
|
||||||
proc { |ability,user,target,move,mults,baseDmg,type|
|
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,
|
BattleHandlers::DamageCalcUserAbility.add(:SLOWSTART,
|
||||||
proc { |ability,user,target,move,mults,baseDmg,type|
|
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?
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
BattleHandlers::DamageCalcUserAbility.add(:SOLARPOWER,
|
BattleHandlers::DamageCalcUserAbility.add(:SOLARPOWER,
|
||||||
proc { |ability,user,target,move,mults,baseDmg,type|
|
proc { |ability,user,target,move,mults,baseDmg,type|
|
||||||
w = user.battle.pbWeather
|
w = user.battle.pbWeather
|
||||||
if move.specialMove? && (w==PBWeather::Sun || w==PBWeather::HarshSun)
|
if move.specialMove? && (w == PBWeather::Sun || w == PBWeather::HarshSun)
|
||||||
mults[ATK_MULT] *= 1.5
|
mults[:attack_multiplier] *= 1.5
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@@ -1045,77 +1045,77 @@ BattleHandlers::DamageCalcUserAbility.add(:SOLARPOWER,
|
|||||||
BattleHandlers::DamageCalcUserAbility.add(:SNIPER,
|
BattleHandlers::DamageCalcUserAbility.add(:SNIPER,
|
||||||
proc { |ability,user,target,move,mults,baseDmg,type|
|
proc { |ability,user,target,move,mults,baseDmg,type|
|
||||||
if target.damageState.critical
|
if target.damageState.critical
|
||||||
mults[FINAL_DMG_MULT] *= 1.5
|
mults[:final_damage_multiplier] *= 1.5
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
BattleHandlers::DamageCalcUserAbility.add(:STAKEOUT,
|
BattleHandlers::DamageCalcUserAbility.add(:STAKEOUT,
|
||||||
proc { |ability,user,target,move,mults,baseDmg,type|
|
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,
|
BattleHandlers::DamageCalcUserAbility.add(:STEELWORKER,
|
||||||
proc { |ability,user,target,move,mults,baseDmg,type|
|
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,
|
BattleHandlers::DamageCalcUserAbility.add(:STRONGJAW,
|
||||||
proc { |ability,user,target,move,mults,baseDmg,type|
|
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,
|
BattleHandlers::DamageCalcUserAbility.add(:SWARM,
|
||||||
proc { |ability,user,target,move,mults,baseDmg,type|
|
proc { |ability,user,target,move,mults,baseDmg,type|
|
||||||
if user.hp<=user.totalhp/3 && type == :BUG
|
if user.hp <= user.totalhp / 3 && type == :BUG
|
||||||
mults[ATK_MULT] *= 1.5
|
mults[:attack_multiplier] *= 1.5
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
BattleHandlers::DamageCalcUserAbility.add(:TECHNICIAN,
|
BattleHandlers::DamageCalcUserAbility.add(:TECHNICIAN,
|
||||||
proc { |ability,user,target,move,mults,baseDmg,type|
|
proc { |ability,user,target,move,mults,baseDmg,type|
|
||||||
if user.index!=target.index && move && move.id != :STRUGGLE &&
|
if user.index != target.index && move && move.id != :STRUGGLE &&
|
||||||
baseDmg*mults[BASE_DMG_MULT]<=60
|
baseDmg * mults[:base_damage_multiplier] <= 60
|
||||||
mults[BASE_DMG_MULT] *= 1.5
|
mults[:base_damage_multiplier] *= 1.5
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
BattleHandlers::DamageCalcUserAbility.add(:TINTEDLENS,
|
BattleHandlers::DamageCalcUserAbility.add(:TINTEDLENS,
|
||||||
proc { |ability,user,target,move,mults,baseDmg,type|
|
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,
|
BattleHandlers::DamageCalcUserAbility.add(:TORRENT,
|
||||||
proc { |ability,user,target,move,mults,baseDmg,type|
|
proc { |ability,user,target,move,mults,baseDmg,type|
|
||||||
if user.hp<=user.totalhp/3 && type == :WATER
|
if user.hp <= user.totalhp / 3 && type == :WATER
|
||||||
mults[ATK_MULT] *= 1.5
|
mults[:attack_multiplier] *= 1.5
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
BattleHandlers::DamageCalcUserAbility.add(:TOUGHCLAWS,
|
BattleHandlers::DamageCalcUserAbility.add(:TOUGHCLAWS,
|
||||||
proc { |ability,user,target,move,mults,baseDmg,type|
|
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,
|
BattleHandlers::DamageCalcUserAbility.add(:TOXICBOOST,
|
||||||
proc { |ability,user,target,move,mults,baseDmg,type|
|
proc { |ability,user,target,move,mults,baseDmg,type|
|
||||||
if user.poisoned? && move.physicalMove?
|
if user.poisoned? && move.physicalMove?
|
||||||
mults[BASE_DMG_MULT] *= 1.5
|
mults[:base_damage_multiplier] *= 1.5
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
BattleHandlers::DamageCalcUserAbility.add(:WATERBUBBLE,
|
BattleHandlers::DamageCalcUserAbility.add(:WATERBUBBLE,
|
||||||
proc { |ability,user,target,move,mults,baseDmg,type|
|
proc { |ability,user,target,move,mults,baseDmg,type|
|
||||||
mults[ATK_MULT] *= 2 if type == :WATER
|
mults[:attack_multiplier] *= 2 if type == :WATER
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -1126,15 +1126,15 @@ BattleHandlers::DamageCalcUserAbility.add(:WATERBUBBLE,
|
|||||||
BattleHandlers::DamageCalcUserAllyAbility.add(:BATTERY,
|
BattleHandlers::DamageCalcUserAllyAbility.add(:BATTERY,
|
||||||
proc { |ability,user,target,move,mults,baseDmg,type|
|
proc { |ability,user,target,move,mults,baseDmg,type|
|
||||||
next if !move.specialMove?
|
next if !move.specialMove?
|
||||||
mults[FINAL_DMG_MULT] *= 1.3
|
mults[:final_damage_multiplier] *= 1.3
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
BattleHandlers::DamageCalcUserAllyAbility.add(:FLOWERGIFT,
|
BattleHandlers::DamageCalcUserAllyAbility.add(:FLOWERGIFT,
|
||||||
proc { |ability,user,target,move,mults,baseDmg,type|
|
proc { |ability,user,target,move,mults,baseDmg,type|
|
||||||
w = user.battle.pbWeather
|
w = user.battle.pbWeather
|
||||||
if move.physicalMove? && (w==PBWeather::Sun || w==PBWeather::HarshSun)
|
if move.physicalMove? && (w == PBWeather::Sun || w == PBWeather::HarshSun)
|
||||||
mults[ATK_MULT] *= 1.5
|
mults[:attack_multiplier] *= 1.5
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@@ -1145,14 +1145,14 @@ BattleHandlers::DamageCalcUserAllyAbility.add(:FLOWERGIFT,
|
|||||||
|
|
||||||
BattleHandlers::DamageCalcTargetAbility.add(:DRYSKIN,
|
BattleHandlers::DamageCalcTargetAbility.add(:DRYSKIN,
|
||||||
proc { |ability,user,target,move,mults,baseDmg,type|
|
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,
|
BattleHandlers::DamageCalcTargetAbility.add(:FILTER,
|
||||||
proc { |ability,user,target,move,mults,baseDmg,type|
|
proc { |ability,user,target,move,mults,baseDmg,type|
|
||||||
if PBTypeEffectiveness.superEffective?(target.damageState.typeMod)
|
if PBTypeEffectiveness.superEffective?(target.damageState.typeMod)
|
||||||
mults[FINAL_DMG_MULT] *= 0.75
|
mults[:final_damage_multiplier] *= 0.75
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@@ -1162,62 +1162,62 @@ BattleHandlers::DamageCalcTargetAbility.copy(:FILTER,:SOLIDROCK)
|
|||||||
BattleHandlers::DamageCalcTargetAbility.add(:FLOWERGIFT,
|
BattleHandlers::DamageCalcTargetAbility.add(:FLOWERGIFT,
|
||||||
proc { |ability,user,target,move,mults,baseDmg,type|
|
proc { |ability,user,target,move,mults,baseDmg,type|
|
||||||
w = user.battle.pbWeather
|
w = user.battle.pbWeather
|
||||||
if move.specialMove? && (w==PBWeather::Sun || w==PBWeather::HarshSun)
|
if move.specialMove? && (w == PBWeather::Sun || w == PBWeather::HarshSun)
|
||||||
mults[DEF_MULT] *= 1.5
|
mults[:defense_multiplier] *= 1.5
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
BattleHandlers::DamageCalcTargetAbility.add(:FLUFFY,
|
BattleHandlers::DamageCalcTargetAbility.add(:FLUFFY,
|
||||||
proc { |ability,user,target,move,mults,baseDmg,type|
|
proc { |ability,user,target,move,mults,baseDmg,type|
|
||||||
mults[FINAL_DMG_MULT] *= 2 if move.calcType == :FIRE
|
mults[:final_damage_multiplier] *= 2 if move.calcType == :FIRE
|
||||||
mults[FINAL_DMG_MULT] /= 2 if move.contactMove?
|
mults[:final_damage_multiplier] /= 2 if move.contactMove?
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
BattleHandlers::DamageCalcTargetAbility.add(:FURCOAT,
|
BattleHandlers::DamageCalcTargetAbility.add(:FURCOAT,
|
||||||
proc { |ability,user,target,move,mults,baseDmg,type|
|
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,
|
BattleHandlers::DamageCalcTargetAbility.add(:GRASSPELT,
|
||||||
proc { |ability,user,target,move,mults,baseDmg,type|
|
proc { |ability,user,target,move,mults,baseDmg,type|
|
||||||
if user.battle.field.terrain==PBBattleTerrains::Grassy
|
if user.battle.field.terrain == PBBattleTerrains::Grassy
|
||||||
mults[DEF_MULT] *= 1.5
|
mults[:defense_multiplier] *= 1.5
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
BattleHandlers::DamageCalcTargetAbility.add(:HEATPROOF,
|
BattleHandlers::DamageCalcTargetAbility.add(:HEATPROOF,
|
||||||
proc { |ability,user,target,move,mults,baseDmg,type|
|
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,
|
BattleHandlers::DamageCalcTargetAbility.add(:MARVELSCALE,
|
||||||
proc { |ability,user,target,move,mults,baseDmg,type|
|
proc { |ability,user,target,move,mults,baseDmg,type|
|
||||||
if target.pbHasAnyStatus? && move.physicalMove?
|
if target.pbHasAnyStatus? && move.physicalMove?
|
||||||
mults[DEF_MULT] *= 1.5
|
mults[:defense_multiplier] *= 1.5
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
BattleHandlers::DamageCalcTargetAbility.add(:MULTISCALE,
|
BattleHandlers::DamageCalcTargetAbility.add(:MULTISCALE,
|
||||||
proc { |ability,user,target,move,mults,baseDmg,type|
|
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,
|
BattleHandlers::DamageCalcTargetAbility.add(:THICKFAT,
|
||||||
proc { |ability,user,target,move,mults,baseDmg,type|
|
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,
|
BattleHandlers::DamageCalcTargetAbility.add(:WATERBUBBLE,
|
||||||
proc { |ability,user,target,move,mults,baseDmg,type|
|
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,
|
BattleHandlers::DamageCalcTargetAbilityNonIgnorable.add(:PRISMARMOR,
|
||||||
proc { |ability,user,target,move,mults,baseDmg,type|
|
proc { |ability,user,target,move,mults,baseDmg,type|
|
||||||
if PBTypeEffectiveness.superEffective?(target.damageState.typeMod)
|
if PBTypeEffectiveness.superEffective?(target.damageState.typeMod)
|
||||||
mults[FINAL_DMG_MULT] *= 0.75
|
mults[:final_damage_multiplier] *= 0.75
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@@ -1236,7 +1236,7 @@ BattleHandlers::DamageCalcTargetAbilityNonIgnorable.add(:PRISMARMOR,
|
|||||||
BattleHandlers::DamageCalcTargetAbilityNonIgnorable.add(:SHADOWSHIELD,
|
BattleHandlers::DamageCalcTargetAbilityNonIgnorable.add(:SHADOWSHIELD,
|
||||||
proc { |ability,user,target,move,mults,baseDmg,type|
|
proc { |ability,user,target,move,mults,baseDmg,type|
|
||||||
if target.hp==target.totalhp
|
if target.hp==target.totalhp
|
||||||
mults[FINAL_DMG_MULT] /= 2
|
mults[:final_damage_multiplier] /= 2
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@@ -1248,15 +1248,15 @@ BattleHandlers::DamageCalcTargetAbilityNonIgnorable.add(:SHADOWSHIELD,
|
|||||||
BattleHandlers::DamageCalcTargetAllyAbility.add(:FLOWERGIFT,
|
BattleHandlers::DamageCalcTargetAllyAbility.add(:FLOWERGIFT,
|
||||||
proc { |ability,user,target,move,mults,baseDmg,type|
|
proc { |ability,user,target,move,mults,baseDmg,type|
|
||||||
w = user.battle.pbWeather
|
w = user.battle.pbWeather
|
||||||
if move.specialMove? && (w==PBWeather::Sun || w==PBWeather::HarshSun)
|
if move.specialMove? && (w == PBWeather::Sun || w == PBWeather::HarshSun)
|
||||||
mults[DEF_MULT] *= 1.5
|
mults[:defense_multiplier] *= 1.5
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
BattleHandlers::DamageCalcTargetAllyAbility.add(:FRIENDGUARD,
|
BattleHandlers::DamageCalcTargetAllyAbility.add(:FRIENDGUARD,
|
||||||
proc { |ability,user,target,move,mults,baseDmg,type|
|
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,
|
BattleHandlers::AccuracyCalcUserItem.add(:WIDELENS,
|
||||||
proc { |item,mods,user,target,move,type|
|
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 &&
|
if (target.battle.choices[target.index][0]!=:UseMove &&
|
||||||
target.battle.choices[target.index][0]!=:Shift) ||
|
target.battle.choices[target.index][0]!=:Shift) ||
|
||||||
target.movedThisRound?
|
target.movedThisRound?
|
||||||
mods[ACC_MULT] *= 1.2
|
mods[:accuracy_multiplier] *= 1.2
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@@ -432,7 +432,7 @@ BattleHandlers::AccuracyCalcUserItem.add(:ZOOMLENS,
|
|||||||
|
|
||||||
BattleHandlers::AccuracyCalcTargetItem.add(:BRIGHTPOWDER,
|
BattleHandlers::AccuracyCalcTargetItem.add(:BRIGHTPOWDER,
|
||||||
proc { |item,mods,user,target,move,type|
|
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,
|
BattleHandlers::DamageCalcUserItem.add(:ADAMANTORB,
|
||||||
proc { |item,user,target,move,mults,baseDmg,type|
|
proc { |item,user,target,move,mults,baseDmg,type|
|
||||||
if user.isSpecies?(:DIALGA) && (type == :DRAGON || type == :STEEL)
|
if user.isSpecies?(:DIALGA) && (type == :DRAGON || type == :STEEL)
|
||||||
mults[BASE_DMG_MULT] *= 1.2
|
mults[:base_damage_multiplier] *= 1.2
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
BattleHandlers::DamageCalcUserItem.add(:BLACKBELT,
|
BattleHandlers::DamageCalcUserItem.add(:BLACKBELT,
|
||||||
proc { |item,user,target,move,mults,baseDmg,type|
|
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,
|
BattleHandlers::DamageCalcUserItem.add(:BLACKGLASSES,
|
||||||
proc { |item,user,target,move,mults,baseDmg,type|
|
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,
|
BattleHandlers::DamageCalcUserItem.add(:CHARCOAL,
|
||||||
proc { |item,user,target,move,mults,baseDmg,type|
|
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,
|
BattleHandlers::DamageCalcUserItem.add(:CHOICEBAND,
|
||||||
proc { |item,user,target,move,mults,baseDmg,type|
|
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,
|
BattleHandlers::DamageCalcUserItem.add(:CHOICESPECS,
|
||||||
proc { |item,user,target,move,mults,baseDmg,type|
|
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,
|
BattleHandlers::DamageCalcUserItem.add(:DEEPSEATOOTH,
|
||||||
proc { |item,user,target,move,mults,baseDmg,type|
|
proc { |item,user,target,move,mults,baseDmg,type|
|
||||||
if user.isSpecies?(:CLAMPERL) && move.specialMove?
|
if user.isSpecies?(:CLAMPERL) && move.specialMove?
|
||||||
mults[ATK_MULT] *= 2
|
mults[:attack_multiplier] *= 2
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
BattleHandlers::DamageCalcUserItem.add(:DRAGONFANG,
|
BattleHandlers::DamageCalcUserItem.add(:DRAGONFANG,
|
||||||
proc { |item,user,target,move,mults,baseDmg,type|
|
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,
|
BattleHandlers::DamageCalcUserItem.add(:EXPERTBELT,
|
||||||
proc { |item,user,target,move,mults,baseDmg,type|
|
proc { |item,user,target,move,mults,baseDmg,type|
|
||||||
if PBTypeEffectiveness.superEffective?(target.damageState.typeMod)
|
if PBTypeEffectiveness.superEffective?(target.damageState.typeMod)
|
||||||
mults[FINAL_DMG_MULT] *= 1.2
|
mults[:final_damage_multiplier] *= 1.2
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@@ -573,7 +573,7 @@ BattleHandlers::DamageCalcUserItem.add(:GRASSGEM,
|
|||||||
BattleHandlers::DamageCalcUserItem.add(:GRISEOUSORB,
|
BattleHandlers::DamageCalcUserItem.add(:GRISEOUSORB,
|
||||||
proc { |item,user,target,move,mults,baseDmg,type|
|
proc { |item,user,target,move,mults,baseDmg,type|
|
||||||
if user.isSpecies?(:GIRATINA) && (type == :DRAGON || type == :GHOST)
|
if user.isSpecies?(:GIRATINA) && (type == :DRAGON || type == :GHOST)
|
||||||
mults[BASE_DMG_MULT] *= 1.2
|
mults[:base_damage_multiplier] *= 1.2
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@@ -586,7 +586,7 @@ BattleHandlers::DamageCalcUserItem.add(:GROUNDGEM,
|
|||||||
|
|
||||||
BattleHandlers::DamageCalcUserItem.add(:HARDSTONE,
|
BattleHandlers::DamageCalcUserItem.add(:HARDSTONE,
|
||||||
proc { |item,user,target,move,mults,baseDmg,type|
|
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,
|
BattleHandlers::DamageCalcUserItem.add(:LIFEORB,
|
||||||
proc { |item,user,target,move,mults,baseDmg,type|
|
proc { |item,user,target,move,mults,baseDmg,type|
|
||||||
if !move.is_a?(PokeBattle_Confusion)
|
if !move.is_a?(PokeBattle_Confusion)
|
||||||
mults[FINAL_DMG_MULT] *= 1.3
|
mults[:final_damage_multiplier] *= 1.3
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@@ -609,7 +609,7 @@ BattleHandlers::DamageCalcUserItem.add(:LIFEORB,
|
|||||||
BattleHandlers::DamageCalcUserItem.add(:LIGHTBALL,
|
BattleHandlers::DamageCalcUserItem.add(:LIGHTBALL,
|
||||||
proc { |item,user,target,move,mults,baseDmg,type|
|
proc { |item,user,target,move,mults,baseDmg,type|
|
||||||
if user.isSpecies?(:PIKACHU)
|
if user.isSpecies?(:PIKACHU)
|
||||||
mults[ATK_MULT] *= 2
|
mults[:attack_multiplier] *= 2
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@@ -617,14 +617,14 @@ BattleHandlers::DamageCalcUserItem.add(:LIGHTBALL,
|
|||||||
BattleHandlers::DamageCalcUserItem.add(:LUSTROUSORB,
|
BattleHandlers::DamageCalcUserItem.add(:LUSTROUSORB,
|
||||||
proc { |item,user,target,move,mults,baseDmg,type|
|
proc { |item,user,target,move,mults,baseDmg,type|
|
||||||
if user.isSpecies?(:PALKIA) && (type == :DRAGON || type == :WATER)
|
if user.isSpecies?(:PALKIA) && (type == :DRAGON || type == :WATER)
|
||||||
mults[BASE_DMG_MULT] *= 1.2
|
mults[:base_damage_multiplier] *= 1.2
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
BattleHandlers::DamageCalcUserItem.add(:MAGNET,
|
BattleHandlers::DamageCalcUserItem.add(:MAGNET,
|
||||||
proc { |item,user,target,move,mults,baseDmg,type|
|
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,
|
BattleHandlers::DamageCalcUserItem.add(:METALCOAT,
|
||||||
proc { |item,user,target,move,mults,baseDmg,type|
|
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
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -640,14 +640,14 @@ BattleHandlers::DamageCalcUserItem.copy(:METALCOAT,:IRONPLATE)
|
|||||||
|
|
||||||
BattleHandlers::DamageCalcUserItem.add(:METRONOME,
|
BattleHandlers::DamageCalcUserItem.add(:METRONOME,
|
||||||
proc { |item,user,target,move,mults,baseDmg,type|
|
proc { |item,user,target,move,mults,baseDmg,type|
|
||||||
met = 1+0.2*[user.effects[PBEffects::Metronome],5].min
|
met = 1 + 0.2 * [user.effects[PBEffects::Metronome], 5].min
|
||||||
mults[FINAL_DMG_MULT] *= met
|
mults[:final_damage_multiplier] *= met
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
BattleHandlers::DamageCalcUserItem.add(:MIRACLESEED,
|
BattleHandlers::DamageCalcUserItem.add(:MIRACLESEED,
|
||||||
proc { |item,user,target,move,mults,baseDmg,type|
|
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,
|
BattleHandlers::DamageCalcUserItem.add(:MUSCLEBAND,
|
||||||
proc { |item,user,target,move,mults,baseDmg,type|
|
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,
|
BattleHandlers::DamageCalcUserItem.add(:MYSTICWATER,
|
||||||
proc { |item,user,target,move,mults,baseDmg,type|
|
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,
|
BattleHandlers::DamageCalcUserItem.add(:NEVERMELTICE,
|
||||||
proc { |item,user,target,move,mults,baseDmg,type|
|
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,
|
BattleHandlers::DamageCalcUserItem.add(:PIXIEPLATE,
|
||||||
proc { |item,user,target,move,mults,baseDmg,type|
|
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,
|
BattleHandlers::DamageCalcUserItem.add(:POISONBARB,
|
||||||
proc { |item,user,target,move,mults,baseDmg,type|
|
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,
|
BattleHandlers::DamageCalcUserItem.add(:SHARPBEAK,
|
||||||
proc { |item,user,target,move,mults,baseDmg,type|
|
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,
|
BattleHandlers::DamageCalcUserItem.add(:SILKSCARF,
|
||||||
proc { |item,user,target,move,mults,baseDmg,type|
|
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,
|
BattleHandlers::DamageCalcUserItem.add(:SILVERPOWDER,
|
||||||
proc { |item,user,target,move,mults,baseDmg,type|
|
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,
|
BattleHandlers::DamageCalcUserItem.add(:SOFTSAND,
|
||||||
proc { |item,user,target,move,mults,baseDmg,type|
|
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|
|
proc { |item,user,target,move,mults,baseDmg,type|
|
||||||
next if !user.isSpecies?(:LATIAS) && !user.isSpecies?(:LATIOS)
|
next if !user.isSpecies?(:LATIAS) && !user.isSpecies?(:LATIOS)
|
||||||
if SOUL_DEW_POWERS_UP_TYPES
|
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
|
else
|
||||||
if move.specialMove? && !user.battle.rules["souldewclause"]
|
if move.specialMove? && !user.battle.rules["souldewclause"]
|
||||||
mults[ATK_MULT] *= 1.5
|
mults[:attack_multiplier] *= 1.5
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
@@ -758,7 +758,7 @@ BattleHandlers::DamageCalcUserItem.add(:SOULDEW,
|
|||||||
|
|
||||||
BattleHandlers::DamageCalcUserItem.add(:SPELLTAG,
|
BattleHandlers::DamageCalcUserItem.add(:SPELLTAG,
|
||||||
proc { |item,user,target,move,mults,baseDmg,type|
|
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,
|
BattleHandlers::DamageCalcUserItem.add(:THICKCLUB,
|
||||||
proc { |item,user,target,move,mults,baseDmg,type|
|
proc { |item,user,target,move,mults,baseDmg,type|
|
||||||
if (user.isSpecies?(:CUBONE) || user.isSpecies?(:MAROWAK)) && move.physicalMove?
|
if (user.isSpecies?(:CUBONE) || user.isSpecies?(:MAROWAK)) && move.physicalMove?
|
||||||
mults[ATK_MULT] *= 2
|
mults[:attack_multiplier] *= 2
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
BattleHandlers::DamageCalcUserItem.add(:TWISTEDSPOON,
|
BattleHandlers::DamageCalcUserItem.add(:TWISTEDSPOON,
|
||||||
proc { |item,user,target,move,mults,baseDmg,type|
|
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,
|
BattleHandlers::DamageCalcUserItem.add(:WISEGLASSES,
|
||||||
proc { |item,user,target,move,mults,baseDmg,type|
|
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,
|
BattleHandlers::DamageCalcTargetItem.add(:ASSAULTVEST,
|
||||||
proc { |item,user,target,move,mults,baseDmg,type|
|
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,
|
BattleHandlers::DamageCalcTargetItem.add(:DEEPSEASCALE,
|
||||||
proc { |item,user,target,move,mults,baseDmg,type|
|
proc { |item,user,target,move,mults,baseDmg,type|
|
||||||
if target.isSpecies?(:CLAMPERL) && move.specialMove?
|
if target.isSpecies?(:CLAMPERL) && move.specialMove?
|
||||||
mults[DEF_MULT] *= 2
|
mults[:defense_multiplier] *= 2
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@@ -863,7 +863,7 @@ BattleHandlers::DamageCalcTargetItem.add(:EVIOLITE,
|
|||||||
# affected by Eviolite.
|
# affected by Eviolite.
|
||||||
evos = target.pokemon.species_data.evolutions
|
evos = target.pokemon.species_data.evolutions
|
||||||
if evos.any? { |e| e[1] != PBEvolution::None && !e[3] } # Not a "None", not a prevolution
|
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
|
end
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@@ -889,7 +889,7 @@ BattleHandlers::DamageCalcTargetItem.add(:KEBIABERRY,
|
|||||||
BattleHandlers::DamageCalcTargetItem.add(:METALPOWDER,
|
BattleHandlers::DamageCalcTargetItem.add(:METALPOWDER,
|
||||||
proc { |item,user,target,move,mults,baseDmg,type|
|
proc { |item,user,target,move,mults,baseDmg,type|
|
||||||
if target.isSpecies?(:DITTO) && !target.effects[PBEffects::Transform]
|
if target.isSpecies?(:DITTO) && !target.effects[PBEffects::Transform]
|
||||||
mults[DEF_MULT] *= 1.5
|
mults[:defense_multiplier] *= 1.5
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@@ -935,7 +935,7 @@ BattleHandlers::DamageCalcTargetItem.add(:SOULDEW,
|
|||||||
next if SOUL_DEW_POWERS_UP_TYPES
|
next if SOUL_DEW_POWERS_UP_TYPES
|
||||||
next if !target.isSpecies?(:LATIAS) && !target.isSpecies?(:LATIOS)
|
next if !target.isSpecies?(:LATIAS) && !target.isSpecies?(:LATIOS)
|
||||||
if move.specialMove? && !user.battle.rules["souldewclause"]
|
if move.specialMove? && !user.battle.rules["souldewclause"]
|
||||||
mults[DEF_MULT] *= 1.5
|
mults[:defense_multiplier] *= 1.5
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -130,8 +130,8 @@ def pbConvertTrainerData
|
|||||||
tr_type_names[t.id_number] = t.real_name
|
tr_type_names[t.id_number] = t.real_name
|
||||||
end
|
end
|
||||||
MessageTypes.setMessages(MessageTypes::TrainerTypes, tr_type_names)
|
MessageTypes.setMessages(MessageTypes::TrainerTypes, tr_type_names)
|
||||||
pbSaveTrainerTypes
|
Compiler.write_trainer_types
|
||||||
pbSaveTrainerBattles
|
Compiler.write_trainers
|
||||||
end
|
end
|
||||||
|
|
||||||
def pbNewTrainer(tr_type, tr_name, tr_id, savechanges = true)
|
def pbNewTrainer(tr_type, tr_name, tr_id, savechanges = true)
|
||||||
|
|||||||
@@ -406,7 +406,7 @@ class Pokemon
|
|||||||
return @moves.length
|
return @moves.length
|
||||||
end
|
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
|
# @return [Boolean] whether the Pokémon knows the given move
|
||||||
def hasMove?(move_id)
|
def hasMove?(move_id)
|
||||||
move_data = GameData::Move.try_get(move_id)
|
move_data = GameData::Move.try_get(move_id)
|
||||||
@@ -503,7 +503,7 @@ class Pokemon
|
|||||||
@firstmoves = []
|
@firstmoves = []
|
||||||
end
|
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
|
# @return [Boolean] whether the Pokémon is compatible with the given move
|
||||||
def compatibleWithMove?(move_id)
|
def compatibleWithMove?(move_id)
|
||||||
move_data = GameData::Move.try_get(move_id)
|
move_data = GameData::Move.try_get(move_id)
|
||||||
@@ -821,7 +821,7 @@ class Pokemon
|
|||||||
calcStats
|
calcStats
|
||||||
end
|
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
|
# @return [Boolean] whether this Pokémon is of the specified species
|
||||||
def isSpecies?(check_species)
|
def isSpecies?(check_species)
|
||||||
return @species == check_species || @species == GameData::Species.get(check_species).species
|
return @species == check_species || @species == GameData::Species.get(check_species).species
|
||||||
|
|||||||
@@ -167,6 +167,7 @@ class PokemonRegionMap_Scene
|
|||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# TODO: Why is this PBS file writer here?
|
||||||
def pbSaveMapData
|
def pbSaveMapData
|
||||||
File.open("PBS/townmap.txt","wb") { |f|
|
File.open("PBS/townmap.txt","wb") { |f|
|
||||||
f.write(0xEF.chr)
|
f.write(0xEF.chr)
|
||||||
@@ -179,10 +180,11 @@ class PokemonRegionMap_Scene
|
|||||||
next if !map
|
next if !map
|
||||||
f.write("\#-------------------------------\r\n")
|
f.write("\#-------------------------------\r\n")
|
||||||
f.write(sprintf("[%d]\r\n",i))
|
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]
|
for loc in map[2]
|
||||||
f.write("Point=")
|
f.write("Point = ")
|
||||||
pbWriteCsvRecord(loc,f,[nil,"uussUUUU"])
|
Compiler.pbWriteCsvRecord(loc,f,[nil,"uussUUUU"])
|
||||||
f.write("\r\n")
|
f.write("\r\n")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1059,7 +1059,7 @@ def pbTrainerInfo(pokemonlist,trfile,rules)
|
|||||||
yield(nil) if block_given?
|
yield(nil) if block_given?
|
||||||
save_data(trlists,"Data/trainer_lists.dat")
|
save_data(trlists,"Data/trainer_lists.dat")
|
||||||
yield(nil) if block_given?
|
yield(nil) if block_given?
|
||||||
pbSaveTrainerLists()
|
Compiler.write_trainer_lists
|
||||||
yield(nil) if block_given?
|
yield(nil) if block_given?
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -1298,8 +1298,7 @@ def pbWriteCup(id,rules)
|
|||||||
trlists[cmd][2].push(id) if !trlists[cmd][5]
|
trlists[cmd][2].push(id) if !trlists[cmd][5]
|
||||||
save_data(trlists,"Data/trainer_lists.dat")
|
save_data(trlists,"Data/trainer_lists.dat")
|
||||||
Graphics.update
|
Graphics.update
|
||||||
pbSaveTrainerLists
|
Compiler.write_trainer_lists
|
||||||
Graphics.update
|
|
||||||
end
|
end
|
||||||
return
|
return
|
||||||
# Yes, use new
|
# Yes, use new
|
||||||
|
|||||||
@@ -251,11 +251,6 @@ module Mouse
|
|||||||
@ReleaseCapture = Win32API.new('user32','ReleaseCapture','','i')
|
@ReleaseCapture = Win32API.new('user32','ReleaseCapture','','i')
|
||||||
module_function
|
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)
|
def screen_to_client(x, y)
|
||||||
return nil unless x and y
|
return nil unless x and y
|
||||||
screenToClient = Win32API.new('user32','ScreenToClient',%w(l p),'i')
|
screenToClient = Win32API.new('user32','ScreenToClient',%w(l p),'i')
|
||||||
@@ -264,12 +259,9 @@ module Mouse
|
|||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
def setCapture
|
def getMouseGlobalPos
|
||||||
@SetCapture.call(Win32API.pbFindRgssWindow)
|
pos = [0, 0].pack('ll')
|
||||||
end
|
return (@GetCursorPos.call(pos)!=0) ? pos.unpack('ll') : [nil,nil]
|
||||||
|
|
||||||
def releaseCapture
|
|
||||||
@ReleaseCapture.call
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Returns the position of the mouse relative to the game window.
|
# Returns the position of the mouse relative to the game window.
|
||||||
@@ -283,6 +275,17 @@ module Mouse
|
|||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Unused
|
||||||
|
def setCapture
|
||||||
|
@SetCapture.call(Win32API.pbFindRgssWindow)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Unused
|
||||||
|
def releaseCapture
|
||||||
|
@ReleaseCapture.call
|
||||||
|
end
|
||||||
|
|
||||||
|
# Unused
|
||||||
def del
|
def del
|
||||||
return if @oldcursor==nil
|
return if @oldcursor==nil
|
||||||
@SetClassLong.call(Win32API.pbFindRgssWindow,-12,@oldcursor)
|
@SetClassLong.call(Win32API.pbFindRgssWindow,-12,@oldcursor)
|
||||||
|
|||||||
@@ -63,16 +63,6 @@ def pbSetUpSystem
|
|||||||
pbSetResizeFactor([$PokemonSystem.screensize, 4].min)
|
pbSetResizeFactor([$PokemonSystem.screensize, 4].min)
|
||||||
end
|
end
|
||||||
# Load constants
|
# 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
|
GameData.load_all
|
||||||
if LANGUAGES.length>=2
|
if LANGUAGES.length>=2
|
||||||
pokemonSystem.language = pbChooseLanguage if !havedata
|
pokemonSystem.language = pbChooseLanguage if !havedata
|
||||||
|
|||||||
@@ -235,6 +235,22 @@ def getID(mod,constant)
|
|||||||
return constant
|
return constant
|
||||||
end
|
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
|
end
|
||||||
save_data(encdata, "Data/encounters.dat")
|
save_data(encdata, "Data/encounters.dat")
|
||||||
$PokemonTemp.encountersData = nil
|
$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::DATA[map_id] = GameData::MapMetadata.new(metadata_hash)
|
||||||
GameData::MapMetadata.save
|
GameData::MapMetadata.save
|
||||||
end
|
end
|
||||||
pbSaveMetadata
|
Compiler.write_metadata
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -671,7 +671,7 @@ def pbItemEditor
|
|||||||
GameData::Item::DATA.delete(item)
|
GameData::Item::DATA.delete(item)
|
||||||
GameData::Item::DATA.delete(id_number)
|
GameData::Item::DATA.delete(id_number)
|
||||||
GameData::Item.save
|
GameData::Item.save
|
||||||
pbSaveItems
|
Compiler.write_items
|
||||||
pbMessage(_INTL("The item was deleted."))
|
pbMessage(_INTL("The item was deleted."))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -708,7 +708,7 @@ def pbItemEditor
|
|||||||
# Add item's data to records
|
# Add item's data to records
|
||||||
GameData::Item::DATA[itm.id_number] = GameData::Item::DATA[itm.id] = GameData::Item.new(item_hash)
|
GameData::Item::DATA[itm.id_number] = GameData::Item::DATA[itm.id] = GameData::Item.new(item_hash)
|
||||||
GameData::Item.save
|
GameData::Item.save
|
||||||
pbSaveItems
|
Compiler.write_items
|
||||||
end
|
end
|
||||||
else # Add a new item
|
else # Add a new item
|
||||||
pbItemEditorNew(nil)
|
pbItemEditorNew(nil)
|
||||||
@@ -772,7 +772,7 @@ def pbItemEditorNew(default_name)
|
|||||||
# Add item's data to records
|
# Add item's data to records
|
||||||
GameData::Item::DATA[id_number] = GameData::Item::DATA[id.to_sym] = GameData::Item.new(item_hash)
|
GameData::Item::DATA[id_number] = GameData::Item::DATA[id.to_sym] = GameData::Item.new(item_hash)
|
||||||
GameData::Item.save
|
GameData::Item.save
|
||||||
pbSaveItems
|
Compiler.write_items
|
||||||
pbMessage(_INTL("The item {1} was created (ID: {2}).", name, id.to_s))
|
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.",
|
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))
|
id, id_number))
|
||||||
@@ -857,7 +857,7 @@ def pbPokemonEditor
|
|||||||
GameData::Species::DATA.delete(species)
|
GameData::Species::DATA.delete(species)
|
||||||
GameData::Species::DATA.delete(id_number)
|
GameData::Species::DATA.delete(id_number)
|
||||||
GameData::Species.save
|
GameData::Species.save
|
||||||
pbSavePokemonData
|
Compiler.write_pokemon
|
||||||
pbMessage(_INTL("The species was deleted."))
|
pbMessage(_INTL("The species was deleted."))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -971,7 +971,7 @@ def pbPokemonEditor
|
|||||||
# Add species' data to records
|
# Add species' data to records
|
||||||
GameData::Species::DATA[spec.id_number] = GameData::Species::DATA[spec.id] = GameData::Species.new(species_hash)
|
GameData::Species::DATA[spec.id_number] = GameData::Species::DATA[spec.id] = GameData::Species.new(species_hash)
|
||||||
GameData::Species.save
|
GameData::Species.save
|
||||||
pbSavePokemonData
|
Compiler.write_pokemon
|
||||||
pbMessage(_INTL("Data saved."))
|
pbMessage(_INTL("Data saved."))
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
@@ -1178,7 +1178,7 @@ def pbRegionalDexEditorMain
|
|||||||
when 0 # Save all changes to Dexes
|
when 0 # Save all changes to Dexes
|
||||||
save_data(dex_lists, "Data/regional_dexes.dat")
|
save_data(dex_lists, "Data/regional_dexes.dat")
|
||||||
$PokemonTemp.regionalDexes = nil
|
$PokemonTemp.regionalDexes = nil
|
||||||
pbSaveRegionalDexes
|
Compiler.write_regional_dexes
|
||||||
pbMessage(_INTL("Data saved."))
|
pbMessage(_INTL("Data saved."))
|
||||||
break
|
break
|
||||||
when 1 # Just quit
|
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
|
return retarray
|
||||||
end
|
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
|
# List all members of a class
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
|
|||||||
@@ -284,7 +284,8 @@ class MapScreenScene
|
|||||||
|
|
||||||
def serializeConnectionData
|
def serializeConnectionData
|
||||||
conndata=generateConnectionData()
|
conndata=generateConnectionData()
|
||||||
pbSerializeConnectionData(conndata,@mapinfos)
|
save_data(conndata, "Data/map_connections.dat")
|
||||||
|
Compiler.write_connections
|
||||||
@mapconns=conndata
|
@mapconns=conndata
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -575,7 +576,7 @@ class MapScreenScene
|
|||||||
MapFactoryHelper.clear
|
MapFactoryHelper.clear
|
||||||
save_data(@encdata,"Data/encounters.dat")
|
save_data(@encdata,"Data/encounters.dat")
|
||||||
$PokemonTemp.encountersData = nil
|
$PokemonTemp.encountersData = nil
|
||||||
pbSaveEncounterData
|
Compiler.write_encounters
|
||||||
end
|
end
|
||||||
break if pbConfirmMessage(_INTL("Exit from the editor?"))
|
break if pbConfirmMessage(_INTL("Exit from the editor?"))
|
||||||
end
|
end
|
||||||
@@ -32,8 +32,8 @@ def pbAutoPositionAll
|
|||||||
bitmap2.dispose if bitmap2
|
bitmap2.dispose if bitmap2
|
||||||
end
|
end
|
||||||
GameData::Species.save
|
GameData::Species.save
|
||||||
pbSavePokemonData
|
Compiler.write_pokemon
|
||||||
pbSavePokemonFormsData
|
Compiler.write_pokemon_forms
|
||||||
end
|
end
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
@@ -97,8 +97,8 @@ class SpritePositioner
|
|||||||
|
|
||||||
def pbSaveMetrics
|
def pbSaveMetrics
|
||||||
GameData::Species.save
|
GameData::Species.save
|
||||||
pbSavePokemonData
|
Compiler.write_pokemon
|
||||||
pbSavePokemonFormsData
|
Compiler.write_pokemon_forms
|
||||||
end
|
end
|
||||||
|
|
||||||
def update
|
def update
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -76,6 +76,19 @@ module Compiler
|
|||||||
return line
|
return line
|
||||||
end
|
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
|
# PBS file readers
|
||||||
#=============================================================================
|
#=============================================================================
|
||||||
@@ -115,7 +128,7 @@ module Compiler
|
|||||||
yield lastsection,sectionname if havesection
|
yield lastsection,sectionname if havesection
|
||||||
end
|
end
|
||||||
|
|
||||||
# Used for pokemon.txt
|
# Used for types.txt, pokemon.txt, metadata.txt
|
||||||
def pbEachFileSection(f)
|
def pbEachFileSection(f)
|
||||||
pbEachFileSectionEx(f) { |section,name|
|
pbEachFileSectionEx(f) { |section,name|
|
||||||
yield section,name.to_i if block_given? && name[/^\d+$/]
|
yield section,name.to_i if block_given? && name[/^\d+$/]
|
||||||
@@ -201,7 +214,7 @@ module Compiler
|
|||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
# Used for connections.txt, abilities.txt, moves.txt, trainertypes.txt
|
# Used for connections.txt, abilities.txt, moves.txt, regionaldexes.txt
|
||||||
def pbCompilerEachPreppedLine(filename)
|
def pbCompilerEachPreppedLine(filename)
|
||||||
File.open(filename,"rb") { |f|
|
File.open(filename,"rb") { |f|
|
||||||
FileLineData.file = filename
|
FileLineData.file = filename
|
||||||
@@ -514,34 +527,73 @@ module Compiler
|
|||||||
end
|
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)
|
def pbWriteCsvRecord(record,file,schema)
|
||||||
if x<0 || x>255
|
rec = (record.is_a?(Array)) ? record.clone : [record]
|
||||||
raise _INTL("The value \"{1}\" must be from 0 through 255 (00-FF in hex), got a value of {2}\r\n{3}",
|
for i in 0...schema[1].length
|
||||||
valuename,x,FileLineData.linereport)
|
chr = schema[1][i,1]
|
||||||
end
|
file.write(",") if i>0
|
||||||
end
|
if rec[i].nil?
|
||||||
|
# do nothing
|
||||||
def pbCheckSignedByte(x,valuename)
|
elsif rec[i].is_a?(String)
|
||||||
if x<-128 || x>127
|
file.write(csvQuote(rec[i]))
|
||||||
raise _INTL("The value \"{1}\" must be from -128 through 127, got a value of {2}\r\n{3}",
|
elsif rec[i].is_a?(Symbol)
|
||||||
valuename,x,FileLineData.linereport)
|
file.write(csvQuote(rec[i].to_s))
|
||||||
end
|
elsif rec[i]==true
|
||||||
end
|
file.write("true")
|
||||||
|
elsif rec[i]==false
|
||||||
def pbCheckWord(x,valuename)
|
file.write("false")
|
||||||
if x<0 || x>65535
|
elsif rec[i].is_a?(Numeric)
|
||||||
raise _INTL("The value \"{1}\" must be from 0 through 65535 (0000-FFFF in hex), got a value of {2}\r\n{3}",
|
case chr
|
||||||
valuename,x,FileLineData.linereport)
|
when "e", "E" # Enumerable
|
||||||
end
|
enumer = schema[2+i]
|
||||||
end
|
if enumer.is_a?(Array)
|
||||||
|
file.write(enumer[rec[i]])
|
||||||
def pbCheckSignedWord(x,valuename)
|
elsif enumer.is_a?(Symbol) || enumer.is_a?(String)
|
||||||
if x<-32768 || x>32767
|
mod = Object.const_get(enumer.to_sym)
|
||||||
raise _INTL("The value \"{1}\" must be from -32768 through 32767, got a value of {2}\r\n{3}",
|
file.write(getConstantName(mod,rec[i]))
|
||||||
valuename,x,FileLineData.linereport)
|
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
|
end
|
||||||
|
return record
|
||||||
end
|
end
|
||||||
|
|
||||||
#=============================================================================
|
#=============================================================================
|
||||||
@@ -625,12 +677,14 @@ module Compiler
|
|||||||
MessageTypes.loadMessageFile("Data/messages.dat")
|
MessageTypes.loadMessageFile("Data/messages.dat")
|
||||||
end
|
end
|
||||||
if mustCompile
|
if mustCompile
|
||||||
yield(_INTL("Compiling type data"))
|
|
||||||
compile_types # No dependencies
|
|
||||||
yield(_INTL("Compiling town map data"))
|
yield(_INTL("Compiling town map data"))
|
||||||
compile_town_map # No dependencies
|
compile_town_map # No dependencies
|
||||||
yield(_INTL("Compiling map connection data"))
|
yield(_INTL("Compiling map connection data"))
|
||||||
compile_connections # No dependencies
|
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"))
|
yield(_INTL("Compiling ability data"))
|
||||||
compile_abilities # No dependencies
|
compile_abilities # No dependencies
|
||||||
yield(_INTL("Compiling move data"))
|
yield(_INTL("Compiling move data"))
|
||||||
@@ -645,22 +699,20 @@ module Compiler
|
|||||||
compile_pokemon_forms # Depends on Species, Move, Item, Type, Ability
|
compile_pokemon_forms # Depends on Species, Move, Item, Type, Ability
|
||||||
yield(_INTL("Compiling machine data"))
|
yield(_INTL("Compiling machine data"))
|
||||||
compile_move_compatibilities # Depends on Species, Move
|
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"))
|
yield(_INTL("Compiling shadow moveset data"))
|
||||||
compile_shadow_movesets # Depends on Species, Move
|
compile_shadow_movesets # Depends on Species, Move
|
||||||
yield(_INTL("Compiling Regional Dexes"))
|
yield(_INTL("Compiling Regional Dexes"))
|
||||||
compile_regional_dexes # Depends on Species
|
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"))
|
yield(_INTL("Compiling animations"))
|
||||||
compile_animations
|
compile_animations
|
||||||
yield(_INTL("Converting events"))
|
yield(_INTL("Converting events"))
|
||||||
@@ -698,8 +750,7 @@ module Compiler
|
|||||||
"trainer_lists.dat",
|
"trainer_lists.dat",
|
||||||
"trainer_types.dat",
|
"trainer_types.dat",
|
||||||
"trainers.dat",
|
"trainers.dat",
|
||||||
"types.dat",
|
"types.dat"
|
||||||
"Constants.rxdata"
|
|
||||||
]
|
]
|
||||||
textFiles = [
|
textFiles = [
|
||||||
"abilities.txt",
|
"abilities.txt",
|
||||||
@@ -728,7 +779,7 @@ module Compiler
|
|||||||
# If no PBS file, create one and fill it, then recompile
|
# If no PBS file, create one and fill it, then recompile
|
||||||
if !safeIsDirectory?("PBS")
|
if !safeIsDirectory?("PBS")
|
||||||
Dir.mkdir("PBS") rescue nil
|
Dir.mkdir("PBS") rescue nil
|
||||||
pbSaveAllData
|
write_all
|
||||||
mustCompile = true
|
mustCompile = true
|
||||||
end
|
end
|
||||||
# Should recompile if holding Ctrl
|
# 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
|
module_function
|
||||||
|
|
||||||
#=============================================================================
|
#=============================================================================
|
||||||
# Compile metadata
|
# Compile Town Map data
|
||||||
#=============================================================================
|
|
||||||
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
|
|
||||||
#=============================================================================
|
#=============================================================================
|
||||||
def compile_town_map
|
def compile_town_map
|
||||||
nonglobaltypes = {
|
nonglobaltypes = {
|
||||||
@@ -182,36 +93,6 @@ module Compiler
|
|||||||
Graphics.update
|
Graphics.update
|
||||||
end
|
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
|
# Compile phone messages
|
||||||
#=============================================================================
|
#=============================================================================
|
||||||
@@ -251,7 +132,7 @@ module Compiler
|
|||||||
end
|
end
|
||||||
|
|
||||||
#=============================================================================
|
#=============================================================================
|
||||||
# Compile types
|
# Compile type data
|
||||||
#=============================================================================
|
#=============================================================================
|
||||||
def compile_types
|
def compile_types
|
||||||
GameData::Type::DATA.clear
|
GameData::Type::DATA.clear
|
||||||
@@ -325,7 +206,7 @@ module Compiler
|
|||||||
end
|
end
|
||||||
|
|
||||||
#=============================================================================
|
#=============================================================================
|
||||||
# Compile abilities
|
# Compile ability data
|
||||||
#=============================================================================
|
#=============================================================================
|
||||||
def compile_abilities
|
def compile_abilities
|
||||||
GameData::Ability::DATA.clear
|
GameData::Ability::DATA.clear
|
||||||
@@ -359,100 +240,6 @@ module Compiler
|
|||||||
Graphics.update
|
Graphics.update
|
||||||
end
|
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
|
# Compile move data
|
||||||
#=============================================================================
|
#=============================================================================
|
||||||
@@ -510,49 +297,83 @@ module Compiler
|
|||||||
end
|
end
|
||||||
|
|
||||||
#=============================================================================
|
#=============================================================================
|
||||||
# Compile battle animations
|
# Compile item data
|
||||||
#=============================================================================
|
#=============================================================================
|
||||||
def compile_animations
|
def compile_items
|
||||||
begin
|
GameData::Item::DATA.clear
|
||||||
pbanims = load_data("Data/PkmnAnimations.rxdata")
|
item_names = []
|
||||||
rescue
|
item_names_plural = []
|
||||||
pbanims = PBAnimations.new
|
item_descriptions = []
|
||||||
end
|
# Read each line of items.txt at a time and compile it into an item
|
||||||
move2anim = [[],[]]
|
pbCompilerEachCommentedLine("PBS/items.txt") { |line, line_no|
|
||||||
=begin
|
line = pbGetCsvRecord(line, line_no, [0, "vnssuusuuUN"])
|
||||||
anims = load_data("Data/Animations.rxdata")
|
item_number = line[0]
|
||||||
for anim in anims
|
item_symbol = line[1].to_sym
|
||||||
next if !anim || anim.frames.length==1
|
if GameData::Item::DATA[item_number]
|
||||||
found = false
|
raise _INTL("Item ID number '{1}' is used twice.\r\n{2}", item_number, FileLineData.linereport)
|
||||||
for i in 0...pbanims.length
|
elsif GameData::Item::DATA[item_symbol]
|
||||||
if pbanims[i] && pbanims[i].id==anim.id
|
raise _INTL("Item ID '{1}' is used twice.\r\n{2}", item_symbol, FileLineData.linereport)
|
||||||
found = true if pbanims[i].array.length>1
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
pbanims[anim.id] = pbConvertRPGAnimation(anim) if !found
|
# Construct item hash
|
||||||
end
|
item_hash = {
|
||||||
=end
|
:id_number => item_number,
|
||||||
for i in 0...pbanims.length
|
:id => item_symbol,
|
||||||
next if !pbanims[i]
|
:name => line[2],
|
||||||
if pbanims[i].name[/^OppMove\:\s*(.*)$/]
|
:name_plural => line[3],
|
||||||
if GameData::Move.exists?($~[1])
|
:pocket => line[4],
|
||||||
moveid = GameData::Move.get($~[1]).id_number
|
:price => line[5],
|
||||||
move2anim[1][moveid] = i
|
:description => line[6],
|
||||||
end
|
:field_use => line[7],
|
||||||
elsif pbanims[i].name[/^Move\:\s*(.*)$/]
|
:battle_use => line[8],
|
||||||
if GameData::Move.exists?($~[1])
|
:type => line[9]
|
||||||
moveid = GameData::Move.get($~[1]).id_number
|
}
|
||||||
move2anim[0][moveid] = i
|
item_hash[:move] = parseMove(line[10]) if !nil_or_empty?(line[10])
|
||||||
end
|
# Add item's data to records
|
||||||
end
|
GameData::Item::DATA[item_number] = GameData::Item::DATA[item_symbol] = GameData::Item.new(item_hash)
|
||||||
end
|
item_names[item_number] = item_hash[:name]
|
||||||
save_data(move2anim,"Data/move2anim.dat")
|
item_names_plural[item_number] = item_hash[:name_plural]
|
||||||
save_data(pbanims,"Data/PkmnAnimations.rxdata")
|
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
|
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
|
def compile_pokemon
|
||||||
GameData::Species::DATA.clear
|
GameData::Species::DATA.clear
|
||||||
@@ -713,7 +534,7 @@ module Compiler
|
|||||||
end
|
end
|
||||||
|
|
||||||
#=============================================================================
|
#=============================================================================
|
||||||
# Compile Pokémon forms
|
# Compile Pokémon forms data
|
||||||
#=============================================================================
|
#=============================================================================
|
||||||
def compile_pokemon_forms
|
def compile_pokemon_forms
|
||||||
species_names = []
|
species_names = []
|
||||||
@@ -930,8 +751,8 @@ module Compiler
|
|||||||
species_hash[species_data.id].each { |move| species_data.tutor_moves.push(move) }
|
species_hash[species_data.id].each { |move| species_data.tutor_moves.push(move) }
|
||||||
end
|
end
|
||||||
GameData::Species.save
|
GameData::Species.save
|
||||||
pbSavePokemonData
|
Compiler.write_pokemon
|
||||||
pbSavePokemonFormsData
|
Compiler.write_pokemon_forms
|
||||||
begin
|
begin
|
||||||
File.delete("PBS/tm.txt")
|
File.delete("PBS/tm.txt")
|
||||||
rescue SystemCallError
|
rescue SystemCallError
|
||||||
@@ -1003,7 +824,7 @@ module Compiler
|
|||||||
end
|
end
|
||||||
|
|
||||||
#=============================================================================
|
#=============================================================================
|
||||||
# Compile wild encounters
|
# Compile wild encounter data
|
||||||
#=============================================================================
|
#=============================================================================
|
||||||
def compile_encounters
|
def compile_encounters
|
||||||
lines = []
|
lines = []
|
||||||
@@ -1110,7 +931,7 @@ module Compiler
|
|||||||
end
|
end
|
||||||
|
|
||||||
#=============================================================================
|
#=============================================================================
|
||||||
# Compile trainer types
|
# Compile trainer type data
|
||||||
#=============================================================================
|
#=============================================================================
|
||||||
def compile_trainer_types
|
def compile_trainer_types
|
||||||
GameData::TrainerType::DATA.clear
|
GameData::TrainerType::DATA.clear
|
||||||
@@ -1155,7 +976,7 @@ module Compiler
|
|||||||
end
|
end
|
||||||
|
|
||||||
#=============================================================================
|
#=============================================================================
|
||||||
# Compile individual trainers
|
# Compile individual trainer data
|
||||||
#=============================================================================
|
#=============================================================================
|
||||||
def compile_trainers
|
def compile_trainers
|
||||||
trainer_info_types = TrainerData::SCHEMA
|
trainer_info_types = TrainerData::SCHEMA
|
||||||
@@ -1355,52 +1176,11 @@ module Compiler
|
|||||||
#=============================================================================
|
#=============================================================================
|
||||||
# Compile Battle Tower and other Cups trainers/Pokémon
|
# 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
|
def compile_trainer_lists
|
||||||
btTrainersRequiredTypes = {
|
btTrainersRequiredTypes = {
|
||||||
"Trainers" => [0, "s"],
|
"Trainers" => [0, "s"],
|
||||||
"Pokemon" => [1, "s"],
|
"Pokemon" => [1, "s"],
|
||||||
"Challenges" => [2, "*s"]
|
"Challenges" => [2, "*s"]
|
||||||
}
|
}
|
||||||
if !safeExists?("PBS/trainerlists.txt")
|
if !safeExists?("PBS/trainerlists.txt")
|
||||||
File.open("PBS/trainerlists.txt","wb") { |f|
|
File.open("PBS/trainerlists.txt","wb") { |f|
|
||||||
@@ -1462,4 +1242,176 @@ module Compiler
|
|||||||
}
|
}
|
||||||
save_data(sections,"Data/trainer_lists.dat")
|
save_data(sections,"Data/trainer_lists.dat")
|
||||||
end
|
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
|
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