From d53ad4b124fa61bda9022338e49a6d1624db03c1 Mon Sep 17 00:00:00 2001 From: Mathew Velasquez Date: Wed, 6 Apr 2016 13:45:36 -0400 Subject: [PATCH] Improved internationalization support --- binding-mri/module_rpg1.rb | 1476 +++++++++++++++++++++++++++++++++++ scripts/Interpreter 1.rb | 2 +- scripts/Interpreter 3.rb | 2 +- scripts/Main.rb | 1 + scripts/Persistent.rb | 14 +- scripts/Scene_Name.rb | 33 +- scripts/Scene_Title.rb | 1 + scripts/Script.rb | 2 +- scripts/Sprite_Timer.rb | 1 - scripts/Window_Message.rb | 11 +- scripts/Window_NameInput.rb | 266 +++++-- scripts/_scripts.txt | 2 +- scripts/i18n_English.rb | 27 + scripts/i18n_Japanese.rb | 35 + scripts/i18n_Language.rb | 194 ++--- scripts/i18n_Translator.rb | 87 --- src/sharedstate.cpp | 13 - 17 files changed, 1823 insertions(+), 344 deletions(-) create mode 100644 binding-mri/module_rpg1.rb create mode 100644 scripts/i18n_English.rb create mode 100644 scripts/i18n_Japanese.rb delete mode 100644 scripts/i18n_Translator.rb diff --git a/binding-mri/module_rpg1.rb b/binding-mri/module_rpg1.rb new file mode 100644 index 0000000..e6cd4c3 --- /dev/null +++ b/binding-mri/module_rpg1.rb @@ -0,0 +1,1476 @@ +module RPG + module Cache + @cache = {} + def self.load_bitmap(folder_name, filename, hue = 0) + path = folder_name + filename + if not @cache.include?(path) or @cache[path].disposed? + if filename != "" + @cache[path] = Bitmap.new(path) + else + @cache[path] = Bitmap.new(32, 32) + end + end + if hue == 0 + @cache[path] + else + key = [path, hue] + if not @cache.include?(key) or @cache[key].disposed? + @cache[key] = @cache[path].clone + @cache[key].hue_change(hue) + end + @cache[key] + end + end + def self.animation(filename, hue) + self.load_bitmap("Graphics/Animations/", filename, hue) + end + def self.autotile(filename) + self.load_bitmap("Graphics/Autotiles/", filename) + end + def self.battleback(filename) + self.load_bitmap("Graphics/Battlebacks/", filename) + end + def self.battler(filename, hue) + self.load_bitmap("Graphics/Battlers/", filename, hue) + end + def self.character(filename, hue) + self.load_bitmap("Graphics/Characters/", filename, hue) + end + def self.fog(filename, hue) + self.load_bitmap("Graphics/Fogs/", filename, hue) + end + def self.gameover(filename) + self.load_bitmap("Graphics/Gameovers/", filename) + end + def self.icon(filename) + self.load_bitmap("Graphics/Icons/", filename) + end + def self.panorama(filename, hue) + self.load_bitmap("Graphics/Panoramas/", filename, hue) + end + def self.picture(filename) + self.load_bitmap("Graphics/Pictures/", filename) + end + def self.tileset(filename) + self.load_bitmap("Graphics/Tilesets/", filename) + end + def self.title(filename) + self.load_bitmap("Graphics/Titles/", filename) + end + def self.windowskin(filename) + self.load_bitmap("Graphics/Windowskins/", filename) + end + def self.tile(filename, tile_id, hue) + key = [filename, tile_id, hue] + if not @cache.include?(key) or @cache[key].disposed? + @cache[key] = Bitmap.new(32, 32) + x = (tile_id - 384) % 8 * 32 + y = (tile_id - 384) / 8 * 32 + rect = Rect.new(x, y, 32, 32) + @cache[key].blt(0, 0, self.tileset(filename), rect) + @cache[key].hue_change(hue) + end + @cache[key] + end + def self.clear + @cache = {} + GC.start + end + end + + class Sprite < ::Sprite + @@_animations = [] + @@_reference_count = {} + def initialize(viewport = nil) + super(viewport) + @_whiten_duration = 0 + @_appear_duration = 0 + @_escape_duration = 0 + @_collapse_duration = 0 + @_damage_duration = 0 + @_animation_duration = 0 + @_blink = false + end + def dispose + dispose_damage + dispose_animation + dispose_loop_animation + super + end + def whiten + self.blend_type = 0 + self.color.set(255, 255, 255, 128) + self.opacity = 255 + @_whiten_duration = 16 + @_appear_duration = 0 + @_escape_duration = 0 + @_collapse_duration = 0 + end + def appear + self.blend_type = 0 + self.color.set(0, 0, 0, 0) + self.opacity = 0 + @_appear_duration = 16 + @_whiten_duration = 0 + @_escape_duration = 0 + @_collapse_duration = 0 + end + def escape + self.blend_type = 0 + self.color.set(0, 0, 0, 0) + self.opacity = 255 + @_escape_duration = 32 + @_whiten_duration = 0 + @_appear_duration = 0 + @_collapse_duration = 0 + end + def collapse + self.blend_type = 1 + self.color.set(255, 64, 64, 255) + self.opacity = 255 + @_collapse_duration = 48 + @_whiten_duration = 0 + @_appear_duration = 0 + @_escape_duration = 0 + end + def damage(value, critical) + dispose_damage + if value.is_a?(Numeric) + damage_string = value.abs.to_s + else + damage_string = value.to_s + end + bitmap = Bitmap.new(160, 48) + bitmap.font.name = "Arial Black" + bitmap.font.size = 32 + bitmap.font.color.set(0, 0, 0) + bitmap.draw_text(-1, 12-1, 160, 36, damage_string, 1) + bitmap.draw_text(+1, 12-1, 160, 36, damage_string, 1) + bitmap.draw_text(-1, 12+1, 160, 36, damage_string, 1) + bitmap.draw_text(+1, 12+1, 160, 36, damage_string, 1) + if value.is_a?(Numeric) and value < 0 + bitmap.font.color.set(176, 255, 144) + else + bitmap.font.color.set(255, 255, 255) + end + bitmap.draw_text(0, 12, 160, 36, damage_string, 1) + if critical + bitmap.font.size = 20 + bitmap.font.color.set(0, 0, 0) + bitmap.draw_text(-1, -1, 160, 20, "CRITICAL", 1) + bitmap.draw_text(+1, -1, 160, 20, "CRITICAL", 1) + bitmap.draw_text(-1, +1, 160, 20, "CRITICAL", 1) + bitmap.draw_text(+1, +1, 160, 20, "CRITICAL", 1) + bitmap.font.color.set(255, 255, 255) + bitmap.draw_text(0, 0, 160, 20, "CRITICAL", 1) + end + @_damage_sprite = ::Sprite.new(self.viewport) + @_damage_sprite.bitmap = bitmap + @_damage_sprite.ox = 80 + @_damage_sprite.oy = 20 + @_damage_sprite.x = self.x + @_damage_sprite.y = self.y - self.oy / 2 + @_damage_sprite.z = 3000 + @_damage_duration = 40 + end + def animation(animation, hit) + dispose_animation + @_animation = animation + return if @_animation == nil + @_animation_hit = hit + @_animation_duration = @_animation.frame_max + animation_name = @_animation.animation_name + animation_hue = @_animation.animation_hue + bitmap = RPG::Cache.animation(animation_name, animation_hue) + if @@_reference_count.include?(bitmap) + @@_reference_count[bitmap] += 1 + else + @@_reference_count[bitmap] = 1 + end + @_animation_sprites = [] + if @_animation.position != 3 or not @@_animations.include?(animation) + for i in 0..15 + sprite = ::Sprite.new(self.viewport) + sprite.bitmap = bitmap + sprite.visible = false + @_animation_sprites.push(sprite) + end + unless @@_animations.include?(animation) + @@_animations.push(animation) + end + end + update_animation + end + def loop_animation(animation) + return if animation == @_loop_animation + dispose_loop_animation + @_loop_animation = animation + return if @_loop_animation == nil + @_loop_animation_index = 0 + animation_name = @_loop_animation.animation_name + animation_hue = @_loop_animation.animation_hue + bitmap = RPG::Cache.animation(animation_name, animation_hue) + if @@_reference_count.include?(bitmap) + @@_reference_count[bitmap] += 1 + else + @@_reference_count[bitmap] = 1 + end + @_loop_animation_sprites = [] + for i in 0..15 + sprite = ::Sprite.new(self.viewport) + sprite.bitmap = bitmap + sprite.visible = false + @_loop_animation_sprites.push(sprite) + end + update_loop_animation + end + def dispose_damage + if @_damage_sprite != nil + @_damage_sprite.bitmap.dispose + @_damage_sprite.dispose + @_damage_sprite = nil + @_damage_duration = 0 + end + end + def dispose_animation + if @_animation_sprites != nil + sprite = @_animation_sprites[0] + if sprite != nil + @@_reference_count[sprite.bitmap] -= 1 + if @@_reference_count[sprite.bitmap] == 0 + sprite.bitmap.dispose + end + end + for sprite in @_animation_sprites + sprite.dispose + end + @_animation_sprites = nil + @_animation = nil + end + end + def dispose_loop_animation + if @_loop_animation_sprites != nil + sprite = @_loop_animation_sprites[0] + if sprite != nil + @@_reference_count[sprite.bitmap] -= 1 + if @@_reference_count[sprite.bitmap] == 0 + sprite.bitmap.dispose + end + end + for sprite in @_loop_animation_sprites + sprite.dispose + end + @_loop_animation_sprites = nil + @_loop_animation = nil + end + end + def blink_on + unless @_blink + @_blink = true + @_blink_count = 0 + end + end + def blink_off + if @_blink + @_blink = false + self.color.set(0, 0, 0, 0) + end + end + def blink? + @_blink + end + def effect? + @_whiten_duration > 0 or + @_appear_duration > 0 or + @_escape_duration > 0 or + @_collapse_duration > 0 or + @_damage_duration > 0 or + @_animation_duration > 0 + end + def update + super + if @_whiten_duration > 0 + @_whiten_duration -= 1 + self.color.alpha = 128 - (16 - @_whiten_duration) * 10 + end + if @_appear_duration > 0 + @_appear_duration -= 1 + self.opacity = (16 - @_appear_duration) * 16 + end + if @_escape_duration > 0 + @_escape_duration -= 1 + self.opacity = 256 - (32 - @_escape_duration) * 10 + end + if @_collapse_duration > 0 + @_collapse_duration -= 1 + self.opacity = 256 - (48 - @_collapse_duration) * 6 + end + if @_damage_duration > 0 + @_damage_duration -= 1 + case @_damage_duration + when 38..39 + @_damage_sprite.y -= 4 + when 36..37 + @_damage_sprite.y -= 2 + when 34..35 + @_damage_sprite.y += 2 + when 28..33 + @_damage_sprite.y += 4 + end + @_damage_sprite.opacity = 256 - (12 - @_damage_duration) * 32 + if @_damage_duration == 0 + dispose_damage + end + end + if @_animation != nil and (Graphics.frame_count % 2 == 0) + @_animation_duration -= 1 + update_animation + end + if @_loop_animation != nil and (Graphics.frame_count % 2 == 0) + update_loop_animation + @_loop_animation_index += 1 + @_loop_animation_index %= @_loop_animation.frame_max + end + if @_blink + @_blink_count = (@_blink_count + 1) % 32 + if @_blink_count < 16 + alpha = (16 - @_blink_count) * 6 + else + alpha = (@_blink_count - 16) * 6 + end + self.color.set(255, 255, 255, alpha) + end + @@_animations.clear + end + def update_animation + if @_animation_duration > 0 + frame_index = @_animation.frame_max - @_animation_duration + cell_data = @_animation.frames[frame_index].cell_data + position = @_animation.position + animation_set_sprites(@_animation_sprites, cell_data, position) + for timing in @_animation.timings + if timing.frame == frame_index + animation_process_timing(timing, @_animation_hit) + end + end + else + dispose_animation + end + end + def update_loop_animation + frame_index = @_loop_animation_index + cell_data = @_loop_animation.frames[frame_index].cell_data + position = @_loop_animation.position + animation_set_sprites(@_loop_animation_sprites, cell_data, position) + for timing in @_loop_animation.timings + if timing.frame == frame_index + animation_process_timing(timing, true) + end + end + end + def animation_set_sprites(sprites, cell_data, position) + for i in 0..15 + sprite = sprites[i] + pattern = cell_data[i, 0] + if sprite == nil or pattern == nil or pattern == -1 + sprite.visible = false if sprite != nil + next + end + sprite.visible = true + sprite.src_rect.set(pattern % 5 * 192, pattern / 5 * 192, 192, 192) + if position == 3 + if self.viewport != nil + sprite.x = self.viewport.rect.width / 2 + sprite.y = self.viewport.rect.height - 160 + else + sprite.x = 320 + sprite.y = 240 + end + else + sprite.x = self.x - self.ox + self.src_rect.width / 2 + sprite.y = self.y - self.oy + self.src_rect.height / 2 + sprite.y -= self.src_rect.height / 4 if position == 0 + sprite.y += self.src_rect.height / 4 if position == 2 + end + sprite.x += cell_data[i, 1] + sprite.y += cell_data[i, 2] + sprite.z = 2000 + sprite.ox = 96 + sprite.oy = 96 + sprite.zoom_x = cell_data[i, 3] / 100.0 + sprite.zoom_y = cell_data[i, 3] / 100.0 + sprite.angle = cell_data[i, 4] + sprite.mirror = (cell_data[i, 5] == 1) + sprite.opacity = cell_data[i, 6] * self.opacity / 255.0 + sprite.blend_type = cell_data[i, 7] + end + end + def animation_process_timing(timing, hit) + if (timing.condition == 0) or + (timing.condition == 1 and hit == true) or + (timing.condition == 2 and hit == false) + if timing.se.name != "" + se = timing.se + Audio.se_play("Audio/SE/" + se.name, se.volume, se.pitch) + end + case timing.flash_scope + when 1 + self.flash(timing.flash_color, timing.flash_duration * 2) + when 2 + if self.viewport != nil + self.viewport.flash(timing.flash_color, timing.flash_duration * 2) + end + when 3 + self.flash(nil, timing.flash_duration * 2) + end + end + end + def x=(x) + sx = x - self.x + if sx != 0 + if @_animation_sprites != nil + for i in 0..15 + @_animation_sprites[i].x += sx + end + end + if @_loop_animation_sprites != nil + for i in 0..15 + @_loop_animation_sprites[i].x += sx + end + end + end + super + end + def y=(y) + sy = y - self.y + if sy != 0 + if @_animation_sprites != nil + for i in 0..15 + @_animation_sprites[i].y += sy + end + end + if @_loop_animation_sprites != nil + for i in 0..15 + @_loop_animation_sprites[i].y += sy + end + end + end + super + end + end + + class Weather + def initialize(viewport = nil) + @type = 0 + @max = 0 + @ox = 0 + @oy = 0 + color1 = Color.new(255, 255, 255, 255) + color2 = Color.new(255, 255, 255, 128) + @rain_bitmap = Bitmap.new(7, 56) + for i in 0..6 + @rain_bitmap.fill_rect(6-i, i*8, 1, 8, color1) + end + @storm_bitmap = Bitmap.new(34, 64) + for i in 0..31 + @storm_bitmap.fill_rect(33-i, i*2, 1, 2, color2) + @storm_bitmap.fill_rect(32-i, i*2, 1, 2, color1) + @storm_bitmap.fill_rect(31-i, i*2, 1, 2, color2) + end + @snow_bitmap = Bitmap.new(6, 6) + @snow_bitmap.fill_rect(0, 1, 6, 4, color2) + @snow_bitmap.fill_rect(1, 0, 4, 6, color2) + @snow_bitmap.fill_rect(1, 2, 4, 2, color1) + @snow_bitmap.fill_rect(2, 1, 2, 4, color1) + @sprites = [] + for i in 1..40 + sprite = Sprite.new(viewport) + sprite.z = 1000 + sprite.visible = false + sprite.opacity = 0 + @sprites.push(sprite) + end + end + def dispose + for sprite in @sprites + sprite.dispose + end + @rain_bitmap.dispose + @storm_bitmap.dispose + @snow_bitmap.dispose + end + def type=(type) + return if @type == type + @type = type + case @type + when 1 + bitmap = @rain_bitmap + when 2 + bitmap = @storm_bitmap + when 3 + bitmap = @snow_bitmap + else + bitmap = nil + end + for i in 1..40 + sprite = @sprites[i] + if sprite != nil + sprite.visible = (i <= @max) + sprite.bitmap = bitmap + end + end + end + def ox=(ox) + return if @ox == ox; + @ox = ox + for sprite in @sprites + sprite.ox = @ox + end + end + def oy=(oy) + return if @oy == oy; + @oy = oy + for sprite in @sprites + sprite.oy = @oy + end + end + def max=(max) + return if @max == max; + @max = [[max, 0].max, 40].min + for i in 1..40 + sprite = @sprites[i] + if sprite != nil + sprite.visible = (i <= @max) + end + end + end + def update + return if @type == 0 + for i in 1..@max + sprite = @sprites[i] + if sprite == nil + break + end + if @type == 1 + sprite.x -= 2 + sprite.y += 16 + sprite.opacity -= 8 + end + if @type == 2 + sprite.x -= 8 + sprite.y += 16 + sprite.opacity -= 12 + end + if @type == 3 + sprite.x -= 2 + sprite.y += 8 + sprite.opacity -= 8 + end + x = sprite.x - @ox + y = sprite.y - @oy + if sprite.opacity < 64 or x < -50 or x > 750 or y < -300 or y > 500 + sprite.x = rand(800) - 50 + @ox + sprite.y = rand(800) - 200 + @oy + sprite.opacity = 255 + end + end + end + attr_reader :type + attr_reader :max + attr_reader :ox + attr_reader :oy + end + + class Map + def initialize(width, height) + @tileset_id = 1 + @width = width + @height = height + @autoplay_bgm = false + @bgm = RPG::AudioFile.new + @autoplay_bgs = false + @bgs = RPG::AudioFile.new("", 80) + @encounter_list = [] + @encounter_step = 30 + @data = Table.new(width, height, 3) + @events = {} + end + attr_accessor :tileset_id + attr_accessor :width + attr_accessor :height + attr_accessor :autoplay_bgm + attr_accessor :bgm + attr_accessor :autoplay_bgs + attr_accessor :bgs + attr_accessor :encounter_list + attr_accessor :encounter_step + attr_accessor :data + attr_accessor :events + end + + class MapInfo + def initialize + @name = "" + @parent_id = 0 + @order = 0 + @expanded = false + @scroll_x = 0 + @scroll_y = 0 + end + attr_accessor :name + attr_accessor :parent_id + attr_accessor :order + attr_accessor :expanded + attr_accessor :scroll_x + attr_accessor :scroll_y + end + + class Event + class Page + class Condition + def initialize + @switch1_valid = false + @switch2_valid = false + @variable_valid = false + @self_switch_valid = false + @switch1_id = 1 + @switch2_id = 1 + @variable_id = 1 + @variable_value = 0 + @self_switch_ch = "A" + end + attr_accessor :switch1_valid + attr_accessor :switch2_valid + attr_accessor :variable_valid + attr_accessor :self_switch_valid + attr_accessor :switch1_id + attr_accessor :switch2_id + attr_accessor :variable_id + attr_accessor :variable_value + attr_accessor :self_switch_ch + end + + class Graphic + def initialize + @tile_id = 0 + @character_name = "" + @character_hue = 0 + @direction = 2 + @pattern = 0 + @opacity = 255 + @blend_type = 0 + end + attr_accessor :tile_id + attr_accessor :character_name + attr_accessor :character_hue + attr_accessor :direction + attr_accessor :pattern + attr_accessor :opacity + attr_accessor :blend_type + end + + def initialize + @condition = RPG::Event::Page::Condition.new + @graphic = RPG::Event::Page::Graphic.new + @move_type = 0 + @move_speed = 3 + @move_frequency = 3 + @move_route = RPG::MoveRoute.new + @walk_anime = true + @step_anime = false + @direction_fix = false + @through = false + @always_on_top = false + @trigger = 0 + @list = [RPG::EventCommand.new] + end + attr_accessor :condition + attr_accessor :graphic + attr_accessor :move_type + attr_accessor :move_speed + attr_accessor :move_frequency + attr_accessor :move_route + attr_accessor :walk_anime + attr_accessor :step_anime + attr_accessor :direction_fix + attr_accessor :through + attr_accessor :always_on_top + attr_accessor :trigger + attr_accessor :list + end + + def initialize(x, y) + @id = 0 + @name = "" + @x = x + @y = y + @pages = [RPG::Event::Page.new] + end + attr_accessor :id + attr_accessor :name + attr_accessor :x + attr_accessor :y + attr_accessor :pages + end + + class EventCommand + def initialize(code = 0, indent = 0, parameters = []) + @code = code + @indent = indent + @parameters = parameters + end + attr_accessor :code + attr_accessor :indent + attr_accessor :parameters + end + + class MoveRoute + def initialize + @repeat = true + @skippable = false + @list = [RPG::MoveCommand.new] + end + attr_accessor :repeat + attr_accessor :skippable + attr_accessor :list + end + + class MoveCommand + def initialize(code = 0, parameters = []) + @code = code + @parameters = parameters + end + attr_accessor :code + attr_accessor :parameters + end + + class Actor + def initialize + @id = 0 + @name = "" + @class_id = 1 + @initial_level = 1 + @final_level = 99 + @exp_basis = 30 + @exp_inflation = 30 + @character_name = "" + @character_hue = 0 + @battler_name = "" + @battler_hue = 0 + @parameters = Table.new(6,100) + for i in 1..99 + @parameters[0,i] = 500+i*50 + @parameters[1,i] = 500+i*50 + @parameters[2,i] = 50+i*5 + @parameters[3,i] = 50+i*5 + @parameters[4,i] = 50+i*5 + @parameters[5,i] = 50+i*5 + end + @weapon_id = 0 + @armor1_id = 0 + @armor2_id = 0 + @armor3_id = 0 + @armor4_id = 0 + @weapon_fix = false + @armor1_fix = false + @armor2_fix = false + @armor3_fix = false + @armor4_fix = false + end + attr_accessor :id + attr_accessor :name + attr_accessor :class_id + attr_accessor :initial_level + attr_accessor :final_level + attr_accessor :exp_basis + attr_accessor :exp_inflation + attr_accessor :character_name + attr_accessor :character_hue + attr_accessor :battler_name + attr_accessor :battler_hue + attr_accessor :parameters + attr_accessor :weapon_id + attr_accessor :armor1_id + attr_accessor :armor2_id + attr_accessor :armor3_id + attr_accessor :armor4_id + attr_accessor :weapon_fix + attr_accessor :armor1_fix + attr_accessor :armor2_fix + attr_accessor :armor3_fix + attr_accessor :armor4_fix + end + + class Class + class Learning + def initialize + @level = 1 + @skill_id = 1 + end + attr_accessor :level + attr_accessor :skill_id + end + + def initialize + @id = 0 + @name = "" + @position = 0 + @weapon_set = [] + @armor_set = [] + @element_ranks = Table.new(1) + @state_ranks = Table.new(1) + @learnings = [] + end + attr_accessor :id + attr_accessor :name + attr_accessor :position + attr_accessor :weapon_set + attr_accessor :armor_set + attr_accessor :element_ranks + attr_accessor :state_ranks + attr_accessor :learnings + end + + class Skill + def initialize + @id = 0 + @name = "" + @icon_name = "" + @description = "" + @scope = 0 + @occasion = 1 + @animation1_id = 0 + @animation2_id = 0 + @menu_se = RPG::AudioFile.new("", 80) + @common_event_id = 0 + @sp_cost = 0 + @power = 0 + @atk_f = 0 + @eva_f = 0 + @str_f = 0 + @dex_f = 0 + @agi_f = 0 + @int_f = 100 + @hit = 100 + @pdef_f = 0 + @mdef_f = 100 + @variance = 15 + @element_set = [] + @plus_state_set = [] + @minus_state_set = [] + end + attr_accessor :id + attr_accessor :name + attr_accessor :icon_name + attr_accessor :description + attr_accessor :scope + attr_accessor :occasion + attr_accessor :animation1_id + attr_accessor :animation2_id + attr_accessor :menu_se + attr_accessor :common_event_id + attr_accessor :sp_cost + attr_accessor :power + attr_accessor :atk_f + attr_accessor :eva_f + attr_accessor :str_f + attr_accessor :dex_f + attr_accessor :agi_f + attr_accessor :int_f + attr_accessor :hit + attr_accessor :pdef_f + attr_accessor :mdef_f + attr_accessor :variance + attr_accessor :element_set + attr_accessor :plus_state_set + attr_accessor :minus_state_set + end + + class Item + def initialize + @id = 0 + @name = "" + @icon_name = "" + @description = "" + @scope = 0 + @occasion = 0 + @animation1_id = 0 + @animation2_id = 0 + @menu_se = RPG::AudioFile.new("", 80) + @common_event_id = 0 + @price = 0 + @consumable = true + @parameter_type = 0 + @parameter_points = 0 + @recover_hp_rate = 0 + @recover_hp = 0 + @recover_sp_rate = 0 + @recover_sp = 0 + @hit = 100 + @pdef_f = 0 + @mdef_f = 0 + @variance = 0 + @element_set = [] + @plus_state_set = [] + @minus_state_set = [] + end + attr_accessor :id + attr_accessor :name + attr_accessor :icon_name + attr_accessor :description + attr_accessor :scope + attr_accessor :occasion + attr_accessor :animation1_id + attr_accessor :animation2_id + attr_accessor :menu_se + attr_accessor :common_event_id + attr_accessor :price + attr_accessor :consumable + attr_accessor :parameter_type + attr_accessor :parameter_points + attr_accessor :recover_hp_rate + attr_accessor :recover_hp + attr_accessor :recover_sp_rate + attr_accessor :recover_sp + attr_accessor :hit + attr_accessor :pdef_f + attr_accessor :mdef_f + attr_accessor :variance + attr_accessor :element_set + attr_accessor :plus_state_set + attr_accessor :minus_state_set + end + + class Weapon + def initialize + @id = 0 + @name = "" + @icon_name = "" + @description = "" + @animation1_id = 0 + @animation2_id = 0 + @price = 0 + @atk = 0 + @pdef = 0 + @mdef = 0 + @str_plus = 0 + @dex_plus = 0 + @agi_plus = 0 + @int_plus = 0 + @element_set = [] + @plus_state_set = [] + @minus_state_set = [] + end + attr_accessor :id + attr_accessor :name + attr_accessor :icon_name + attr_accessor :description + attr_accessor :animation1_id + attr_accessor :animation2_id + attr_accessor :price + attr_accessor :atk + attr_accessor :pdef + attr_accessor :mdef + attr_accessor :str_plus + attr_accessor :dex_plus + attr_accessor :agi_plus + attr_accessor :int_plus + attr_accessor :element_set + attr_accessor :plus_state_set + attr_accessor :minus_state_set + end + + class Armor + def initialize + @id = 0 + @name = "" + @icon_name = "" + @description = "" + @kind = 0 + @auto_state_id = 0 + @price = 0 + @pdef = 0 + @mdef = 0 + @eva = 0 + @str_plus = 0 + @dex_plus = 0 + @agi_plus = 0 + @int_plus = 0 + @guard_element_set = [] + @guard_state_set = [] + end + attr_accessor :id + attr_accessor :name + attr_accessor :icon_name + attr_accessor :description + attr_accessor :kind + attr_accessor :auto_state_id + attr_accessor :price + attr_accessor :pdef + attr_accessor :mdef + attr_accessor :eva + attr_accessor :str_plus + attr_accessor :dex_plus + attr_accessor :agi_plus + attr_accessor :int_plus + attr_accessor :guard_element_set + attr_accessor :guard_state_set + end + + class Enemy + class Action + def initialize + @kind = 0 + @basic = 0 + @skill_id = 1 + @condition_turn_a = 0 + @condition_turn_b = 1 + @condition_hp = 100 + @condition_level = 1 + @condition_switch_id = 0 + @rating = 5 + end + attr_accessor :kind + attr_accessor :basic + attr_accessor :skill_id + attr_accessor :condition_turn_a + attr_accessor :condition_turn_b + attr_accessor :condition_hp + attr_accessor :condition_level + attr_accessor :condition_switch_id + attr_accessor :rating + end + + def initialize + @id = 0 + @name = "" + @battler_name = "" + @battler_hue = 0 + @maxhp = 500 + @maxsp = 500 + @str = 50 + @dex = 50 + @agi = 50 + @int = 50 + @atk = 100 + @pdef = 100 + @mdef = 100 + @eva = 0 + @animation1_id = 0 + @animation2_id = 0 + @element_ranks = Table.new(1) + @state_ranks = Table.new(1) + @actions = [RPG::Enemy::Action.new] + @exp = 0 + @gold = 0 + @item_id = 0 + @weapon_id = 0 + @armor_id = 0 + @treasure_prob = 100 + end + attr_accessor :id + attr_accessor :name + attr_accessor :battler_name + attr_accessor :battler_hue + attr_accessor :maxhp + attr_accessor :maxsp + attr_accessor :str + attr_accessor :dex + attr_accessor :agi + attr_accessor :int + attr_accessor :atk + attr_accessor :pdef + attr_accessor :mdef + attr_accessor :eva + attr_accessor :animation1_id + attr_accessor :animation2_id + attr_accessor :element_ranks + attr_accessor :state_ranks + attr_accessor :actions + attr_accessor :exp + attr_accessor :gold + attr_accessor :item_id + attr_accessor :weapon_id + attr_accessor :armor_id + attr_accessor :treasure_prob + end + + class Troop + class Member + def initialize + @enemy_id = 1 + @x = 0 + @y = 0 + @hidden = false + @immortal = false + end + attr_accessor :enemy_id + attr_accessor :x + attr_accessor :y + attr_accessor :hidden + attr_accessor :immortal + end + + class Page + class Condition + def initialize + @turn_valid = false + @enemy_valid = false + @actor_valid = false + @switch_valid = false + @turn_a = 0 + @turn_b = 0 + @enemy_index = 0 + @enemy_hp = 50 + @actor_id = 1 + @actor_hp = 50 + @switch_id = 1 + end + attr_accessor :turn_valid + attr_accessor :enemy_valid + attr_accessor :actor_valid + attr_accessor :switch_valid + attr_accessor :turn_a + attr_accessor :turn_b + attr_accessor :enemy_index + attr_accessor :enemy_hp + attr_accessor :actor_id + attr_accessor :actor_hp + attr_accessor :switch_id + end + + def initialize + @condition = RPG::Troop::Page::Condition.new + @span = 0 + @list = [RPG::EventCommand.new] + end + attr_accessor :condition + attr_accessor :span + attr_accessor :list + end + + def initialize + @id = 0 + @name = "" + @members = [] + @pages = [RPG::BattleEventPage.new] + end + attr_accessor :id + attr_accessor :name + attr_accessor :members + attr_accessor :pages + end + + class State + def initialize + @id = 0 + @name = "" + @animation_id = 0 + @restriction = 0 + @nonresistance = false + @zero_hp = false + @cant_get_exp = false + @cant_evade = false + @slip_damage = false + @rating = 5 + @hit_rate = 100 + @maxhp_rate = 100 + @maxsp_rate = 100 + @str_rate = 100 + @dex_rate = 100 + @agi_rate = 100 + @int_rate = 100 + @atk_rate = 100 + @pdef_rate = 100 + @mdef_rate = 100 + @eva = 0 + @battle_only = true + @hold_turn = 0 + @auto_release_prob = 0 + @shock_release_prob = 0 + @guard_element_set = [] + @plus_state_set = [] + @minus_state_set = [] + end + attr_accessor :id + attr_accessor :name + attr_accessor :animation_id + attr_accessor :restriction + attr_accessor :nonresistance + attr_accessor :zero_hp + attr_accessor :cant_get_exp + attr_accessor :cant_evade + attr_accessor :slip_damage + attr_accessor :rating + attr_accessor :hit_rate + attr_accessor :maxhp_rate + attr_accessor :maxsp_rate + attr_accessor :str_rate + attr_accessor :dex_rate + attr_accessor :agi_rate + attr_accessor :int_rate + attr_accessor :atk_rate + attr_accessor :pdef_rate + attr_accessor :mdef_rate + attr_accessor :eva + attr_accessor :battle_only + attr_accessor :hold_turn + attr_accessor :auto_release_prob + attr_accessor :shock_release_prob + attr_accessor :guard_element_set + attr_accessor :plus_state_set + attr_accessor :minus_state_set + end + + class Animation + class Frame + def initialize + @cell_max = 0 + @cell_data = Table.new(0, 0) + end + attr_accessor :cell_max + attr_accessor :cell_data + end + + class Timing + def initialize + @frame = 0 + @se = RPG::AudioFile.new("", 80) + @flash_scope = 0 + @flash_color = Color.new(255,255,255,255) + @flash_duration = 5 + @condition = 0 + end + attr_accessor :frame + attr_accessor :se + attr_accessor :flash_scope + attr_accessor :flash_color + attr_accessor :flash_duration + attr_accessor :condition + end + + def initialize + @id = 0 + @name = "" + @animation_name = "" + @animation_hue = 0 + @position = 1 + @frame_max = 1 + @frames = [RPG::Animation::Frame.new] + @timings = [] + end + attr_accessor :id + attr_accessor :name + attr_accessor :animation_name + attr_accessor :animation_hue + attr_accessor :position + attr_accessor :frame_max + attr_accessor :frames + attr_accessor :timings + end + + class Tileset + def initialize + @id = 0 + @name = "" + @tileset_name = "" + @autotile_names = [""]*7 + @panorama_name = "" + @panorama_hue = 0 + @fog_name = "" + @fog_hue = 0 + @fog_opacity = 64 + @fog_blend_type = 0 + @fog_zoom = 200 + @fog_sx = 0 + @fog_sy = 0 + @battleback_name = "" + @passages = Table.new(384) + @priorities = Table.new(384) + @priorities[0] = 5 + @terrain_tags = Table.new(384) + end + attr_accessor :id + attr_accessor :name + attr_accessor :tileset_name + attr_accessor :autotile_names + attr_accessor :panorama_name + attr_accessor :panorama_hue + attr_accessor :fog_name + attr_accessor :fog_hue + attr_accessor :fog_opacity + attr_accessor :fog_blend_type + attr_accessor :fog_zoom + attr_accessor :fog_sx + attr_accessor :fog_sy + attr_accessor :battleback_name + attr_accessor :passages + attr_accessor :priorities + attr_accessor :terrain_tags + end + + class CommonEvent + def initialize + @id = 0 + @name = "" + @trigger = 0 + @switch_id = 1 + @list = [RPG::EventCommand.new] + end + attr_accessor :id + attr_accessor :name + attr_accessor :trigger + attr_accessor :switch_id + attr_accessor :list + end + + class System + class Words + def initialize + @gold = "" + @hp = "" + @sp = "" + @str = "" + @dex = "" + @agi = "" + @int = "" + @atk = "" + @pdef = "" + @mdef = "" + @weapon = "" + @armor1 = "" + @armor2 = "" + @armor3 = "" + @armor4 = "" + @attack = "" + @skill = "" + @guard = "" + @item = "" + @equip = "" + end + attr_accessor :gold + attr_accessor :hp + attr_accessor :sp + attr_accessor :str + attr_accessor :dex + attr_accessor :agi + attr_accessor :int + attr_accessor :atk + attr_accessor :pdef + attr_accessor :mdef + attr_accessor :weapon + attr_accessor :armor1 + attr_accessor :armor2 + attr_accessor :armor3 + attr_accessor :armor4 + attr_accessor :attack + attr_accessor :skill + attr_accessor :guard + attr_accessor :item + attr_accessor :equip + end + + class TestBattler + def initialize + @actor_id = 1 + @level = 1 + @weapon_id = 0 + @armor1_id = 0 + @armor2_id = 0 + @armor3_id = 0 + @armor4_id = 0 + end + attr_accessor :actor_id + attr_accessor :level + attr_accessor :weapon_id + attr_accessor :armor1_id + attr_accessor :armor2_id + attr_accessor :armor3_id + attr_accessor :armor4_id + end + + def initialize + @magic_number = 0 + @party_members = [1] + @elements = [nil, ""] + @switches = [nil, ""] + @variables = [nil, ""] + @windowskin_name = "" + @title_name = "" + @gameover_name = "" + @battle_transition = "" + @title_bgm = RPG::AudioFile.new + @battle_bgm = RPG::AudioFile.new + @battle_end_me = RPG::AudioFile.new + @gameover_me = RPG::AudioFile.new + @cursor_se = RPG::AudioFile.new("", 80) + @decision_se = RPG::AudioFile.new("", 80) + @cancel_se = RPG::AudioFile.new("", 80) + @buzzer_se = RPG::AudioFile.new("", 80) + @equip_se = RPG::AudioFile.new("", 80) + @shop_se = RPG::AudioFile.new("", 80) + @save_se = RPG::AudioFile.new("", 80) + @load_se = RPG::AudioFile.new("", 80) + @battle_start_se = RPG::AudioFile.new("", 80) + @escape_se = RPG::AudioFile.new("", 80) + @actor_collapse_se = RPG::AudioFile.new("", 80) + @enemy_collapse_se = RPG::AudioFile.new("", 80) + @words = RPG::System::Words.new + @test_battlers = [] + @test_troop_id = 1 + @start_map_id = 1 + @start_x = 0 + @start_y = 0 + @battleback_name = "" + @battler_name = "" + @battler_hue = 0 + @edit_map_id = 1 + end + attr_accessor :magic_number + attr_accessor :party_members + attr_accessor :elements + attr_accessor :switches + attr_accessor :variables + attr_accessor :windowskin_name + attr_accessor :title_name + attr_accessor :gameover_name + attr_accessor :battle_transition + attr_accessor :title_bgm + attr_accessor :battle_bgm + attr_accessor :battle_end_me + attr_accessor :gameover_me + attr_accessor :cursor_se + attr_accessor :decision_se + attr_accessor :cancel_se + attr_accessor :buzzer_se + attr_accessor :equip_se + attr_accessor :shop_se + attr_accessor :save_se + attr_accessor :load_se + attr_accessor :battle_start_se + attr_accessor :escape_se + attr_accessor :actor_collapse_se + attr_accessor :enemy_collapse_se + attr_accessor :words + attr_accessor :test_battlers + attr_accessor :test_troop_id + attr_accessor :start_map_id + attr_accessor :start_x + attr_accessor :start_y + attr_accessor :battleback_name + attr_accessor :battler_name + attr_accessor :battler_hue + attr_accessor :edit_map_id + end + + class AudioFile + def initialize(name = "", volume = 100, pitch = 100) + @name = name + @volume = volume + @pitch = pitch + end + attr_accessor :name + attr_accessor :volume + attr_accessor :pitch + end +end diff --git a/scripts/Interpreter 1.rb b/scripts/Interpreter 1.rb index 82d75a6..5391b84 100644 --- a/scripts/Interpreter 1.rb +++ b/scripts/Interpreter 1.rb @@ -235,7 +235,7 @@ class Interpreter #-------------------------------------------------------------------------- def setup_choices(parameters) # Set choices - $game_temp.choices = parameters[0].map{|s| $tr.event(@event_name, s.strip)} + $game_temp.choices = parameters[0].map{|s| Language.tr(s.strip)} # Set cancel processing $game_temp.choice_cancel_type = parameters[1] # Set callback diff --git a/scripts/Interpreter 3.rb b/scripts/Interpreter 3.rb index 3a78a21..a6e1bb7 100644 --- a/scripts/Interpreter 3.rb +++ b/scripts/Interpreter 3.rb @@ -45,7 +45,7 @@ class Interpreter text.strip! # Translate text - text = $tr.event(@event_name, text).clone + text = Language.tr(text).clone # Parse first line for portrait specifier if text[0,1] == '@' diff --git a/scripts/Main.rb b/scripts/Main.rb index 28c8130..2c396d3 100644 --- a/scripts/Main.rb +++ b/scripts/Main.rb @@ -11,6 +11,7 @@ begin # Load persistent data Persistent.load + $persistent.lang = 'ja' # Prepare for transition Graphics.freeze diff --git a/scripts/Persistent.rb b/scripts/Persistent.rb index 345f9aa..069af95 100644 --- a/scripts/Persistent.rb +++ b/scripts/Persistent.rb @@ -28,11 +28,15 @@ class Persistent # Members def lang=(val) - @lang = val - $tr = Translator.new(@lang) - $lang = Language.get(@lang) - Font.default_name = $lang.font - Oneshot.set_yes_no(tr('Yes'), tr('No')) + case val + when String + @lang = LanguageCode.new(val) + when LanguageCode + @lang = val + else + raise 'value passed to Persistent.lang neither String nor LanguageCode' + end + Language.set(@lang) end # MARSHAL diff --git a/scripts/Scene_Name.rb b/scripts/Scene_Name.rb index 8d57c17..86ab842 100644 --- a/scripts/Scene_Name.rb +++ b/scripts/Scene_Name.rb @@ -11,7 +11,7 @@ class Scene_Name def main # Make windows @edit_window = Window_NameEdit.new - @input_window = Window_NameInput.new + @input_window = Language.create_input # Execute transition Graphics.transition # Main loop @@ -56,26 +56,35 @@ class Scene_Name if Input.trigger?(Input::ACTION) # If cursor position is at [OK] if @input_window.character == nil - # If name is empty - if @edit_window.name == "" - # Return to default name - @edit_window.restore_default + # Cursor is at OK or mode buttons + slot = @input_window.mode_button_slot + if slot == -1 + # Cursor is at OK # If name is empty if @edit_window.name == "" - # Play buzzer SE - $game_system.se_play($data_system.buzzer_se) + # Return to default name + @edit_window.restore_default + # If name is empty + if @edit_window.name == "" + # Play buzzer SE + $game_system.se_play($data_system.buzzer_se) + return + end + # Play decision SE + $game_system.se_play($data_system.decision_se) return end + # Change actor name + $game_oneshot.player_name = @edit_window.name # Play decision SE $game_system.se_play($data_system.decision_se) + # Switch to map screen + $scene = Scene_Map.new return end - # Change actor name - $game_oneshot.player_name = @edit_window.name - # Play decision SE + # Cursor is on mode buttons $game_system.se_play($data_system.decision_se) - # Switch to map screen - $scene = Scene_Map.new + @input_window.cycle_mode(slot) return end # If cursor position is at maximum diff --git a/scripts/Scene_Title.rb b/scripts/Scene_Title.rb index b3378fd..662ee80 100644 --- a/scripts/Scene_Title.rb +++ b/scripts/Scene_Title.rb @@ -26,6 +26,7 @@ class Scene_Title $data_tilesets = load_data("Data/Tilesets.rxdata") $data_common_events = load_data("Data/CommonEvents.rxdata") $data_system = load_data("Data/System.rxdata") + Language.initialize_database # Load save game/initialize data $game_temp = Game_Temp.new new_game unless load diff --git a/scripts/Script.rb b/scripts/Script.rb index 382e576..0ea264e 100644 --- a/scripts/Script.rb +++ b/scripts/Script.rb @@ -117,7 +117,7 @@ end # Map specific settings def green_ambient - ambient -50, -50, -50 + ambient -40, -40, -40 end # Travel diff --git a/scripts/Sprite_Timer.rb b/scripts/Sprite_Timer.rb index d791b25..f0ec164 100644 --- a/scripts/Sprite_Timer.rb +++ b/scripts/Sprite_Timer.rb @@ -12,7 +12,6 @@ class Sprite_Timer < Sprite def initialize super self.bitmap = Bitmap.new(88, 48) - self.bitmap.font.name = "Terminus (TTF)" self.bitmap.font.size = 32 self.x = 640 - self.bitmap.width self.y = 0 diff --git a/scripts/Window_Message.rb b/scripts/Window_Message.rb index a419347..e266fdf 100644 --- a/scripts/Window_Message.rb +++ b/scripts/Window_Message.rb @@ -87,7 +87,6 @@ class Window_Message < Window_Selectable # Initialize @blip = BLIP_TIME @text = '' - y = -1 # Pre-process text if $game_temp.message_text != nil && !$game_temp.message_text.empty? @@ -140,6 +139,8 @@ class Window_Message < Window_Selectable break if y >= 4 end end + @text.rstrip! + lines = @text.empty? ? 0 : @text.count("\n") + 1 # Prepare renderer self.contents.clear @@ -154,8 +155,8 @@ class Window_Message < Window_Selectable if $game_temp.choices != nil # Prepare choices, if they fit - if $game_temp.choices.size + y < 4 - @choice_start = y + 1 + if lines + $game_temp.choices.size <= 4 + @choice_start = lines @item_max = $game_temp.choices.size else # Don't call the message callback till we can show all the choices @@ -163,8 +164,8 @@ class Window_Message < Window_Selectable end elsif $game_temp.num_input_variable_id > 0 # Prepare number input, if it fits - if y < 3 - @number_start = y + 1 + if lines < 3 + @number_start = lines else # Don't call the message callback till we get a number @skip_message_proc = true diff --git a/scripts/Window_NameInput.rb b/scripts/Window_NameInput.rb index d81dfc9..7989b5b 100644 --- a/scripts/Window_NameInput.rb +++ b/scripts/Window_NameInput.rb @@ -4,8 +4,38 @@ # This window is used to select text characters on the input name screen. #============================================================================== +class NameInputMode + attr_reader :names + attr_reader :size + attr_accessor :index + attr_accessor :count + + def initialize(names, bitmap) + @names = names + @size = names.map { |n| bitmap.text_size(n).width }.max + @index = 0 + @count = 0 + end + + def cycle + @index = (@index + 1) % @count + end + + def label + @names[(@index + 1) % @count] + end +end + class Window_NameInput < Window_Base - GROUP_WIDTH = 5 + BUTTON_BUFFER = 8 + BUTTON_PADDING = 16 + + attr_accessor :index + attr_accessor :ok_text + attr_accessor :character_tables + attr_accessor :table_height + attr_accessor :char_w + attr_accessor :char_h #-------------------------------------------------------------------------- # * Object Initialization @@ -14,51 +44,123 @@ class Window_NameInput < Window_Base super(0, 128, 640, 352) self.contents = Bitmap.new(width - 32, height - 32) @index = 0 - + @ok_text = "OK" + @char_w = 28 + @char_h = 32 + end + def init # Create dimension information - @character_table = $lang.character_table - @group_height = $lang.character_table_height - @group_size = @group_height * GROUP_WIDTH - @num_groups = @character_table.length / @group_size - @start_x = ((width - 32) - @num_groups * 152 + 12) / 2 - @ok_text = tr("OK") + @table_size = @character_tables.values.first.size + @table_width = @table_size / @table_height + @start_x = ((width - 32) - @table_width * @char_w) / 2 + @start_y = ((height - 32) - (@table_height + 1) * @char_h + BUTTON_BUFFER) / 2 @ok_text_size = self.contents.text_size(@ok_text).width + # Initialize mode information + @character_tables.each_key do |key| + key.each_with_index do |new_max, i| + @modes[i].count = new_max + 1 if @modes[i].count < new_max + 1 + end + end + refresh update_cursor_rect + self + end + #-------------------------------------------------------------------------- + # * Properties + #-------------------------------------------------------------------------- + def set_mode_buttons(buttons) + @modes = buttons.map { |n| NameInputMode.new(n, self.contents) } end #-------------------------------------------------------------------------- # * Text Character Acquisition #-------------------------------------------------------------------------- def character - return @character_table[@index] + return current_table[@index] + end + #-------------------------------------------------------------------------- + # * Mode Button Cursor Positioning + #-------------------------------------------------------------------------- + def mode_button_slot + pos = @index % @table_width + x = 0 + @modes.each_with_index do |mode, i| + size = mode.size + BUTTON_PADDING * 2 + if pos * @char_w >= x && pos * @char_w <= x + size + if (pos + 1) * @char_w - BUTTON_PADDING <= x + size || i < @modes.size - 1 + return i + end + end + x += size + end + return -1 + end + #-------------------------------------------------------------------------- + # * Cycle Current Mode + #-------------------------------------------------------------------------- + def cycle_mode(slot) + @modes[slot].cycle + refresh + end + #-------------------------------------------------------------------------- + # * Get Character Table for Mode + #-------------------------------------------------------------------------- + def current_table + @character_tables[@modes.map { |m| m.index }] end #-------------------------------------------------------------------------- # * Refresh #-------------------------------------------------------------------------- def refresh self.contents.clear - for i in 0...@character_table.length - x = @start_x + i / GROUP_WIDTH / @group_height * 152 + i % GROUP_WIDTH * 28 - y = i / GROUP_WIDTH % @group_height * 32 - self.contents.draw_text(x, y, 28, 32, @character_table[i], 1) + table = current_table + @table_size.times do |i| + x = @start_x + (i % @table_width) * @char_w + y = @start_y + (i / @table_width) * @char_h + self.contents.draw_text(x, y, @char_w, @char_h, table[i], 1) + end + # OK button + self.contents.draw_text(@start_x + @table_width * @char_w - @ok_text_size - BUTTON_PADDING, + @start_y + @table_height * @char_h + BUTTON_BUFFER, + @ok_text_size, @char_h, @ok_text, 1) + # Mode buttons + x = @start_x + BUTTON_PADDING + @modes.each do |mode| + self.contents.draw_text(x, @start_y + @table_height * @char_h + BUTTON_BUFFER, + mode.size, @char_h, mode.label, 1) + x += BUTTON_PADDING * 2 + mode.size end - self.contents.draw_text(@start_x + @num_groups * 152 - 12 - @ok_text_size - 16, - 9 * 32, @ok_text_size, 32, @ok_text, 1) end #-------------------------------------------------------------------------- # * Cursor Rectangle Update #-------------------------------------------------------------------------- def update_cursor_rect - # If cursor is positioned on [OK] - if @index >= @character_table.length - self.cursor_rect.set(@start_x + @num_groups * 152 - 12 - @ok_text_size - 32, - 9 * 32, @ok_text_size + 32, 32) - # If cursor is positioned on anything other than [OK] + if @index >= @table_size + # Cursor is positioned on OK or mode buttons + slot = mode_button_slot + if slot >= 0 + # Cursor is positioned on mode button + x = @start_x + @modes.each_with_index do |mode, i| + if slot == i + self.cursor_rect.set(x, @start_y + @table_height * @char_h + BUTTON_BUFFER, + mode.size + BUTTON_PADDING * 2, @char_h) + break + end + x += BUTTON_PADDING * 2 + mode.size + end + else + # Cursor is positioned on OK button + self.cursor_rect.set(@start_x + @table_width * @char_w - @ok_text_size - BUTTON_PADDING * 2, + @start_y + @table_height * @char_h + BUTTON_BUFFER, + @ok_text_size + 32, @char_h) + end else - x = @start_x + @index / GROUP_WIDTH / @group_height * 152 + @index % GROUP_WIDTH * 28 - y = @index / GROUP_WIDTH % @group_height * 32 - self.cursor_rect.set(x, y, 28, 32) + # Cursor is not positioned on OK or mode buttons + x = @start_x + (@index % @table_width) * @char_w + y = @start_y + (@index / @table_width) * @char_h + self.cursor_rect.set(x, y, @char_w, @char_h) end end #-------------------------------------------------------------------------- @@ -66,77 +168,87 @@ class Window_NameInput < Window_Base #-------------------------------------------------------------------------- def update super - # If cursor is positioned on [OK] - if @index >= @character_table.length - # Cursor down - if Input.trigger?(Input::DOWN) - $game_system.se_play($data_system.cursor_se) - @index -= @character_table.length - end - # Cursor up - if Input.repeat?(Input::UP) - $game_system.se_play($data_system.cursor_se) - @index -= @character_table.length - (@group_size - GROUP_WIDTH) - end - # If cursor is positioned on anything other than [OK] - else - # If right directional button is pushed - if Input.repeat?(Input::RIGHT) - # If directional button pressed down is not a repeat, or - # cursor is not positioned on the right edge - if Input.trigger?(Input::RIGHT) or - @index / @group_size < 3 or @index % GROUP_WIDTH < 4 - # Move cursor to right - $game_system.se_play($data_system.cursor_se) - if @index % GROUP_WIDTH < 4 - @index += 1 - else - @index += @group_size - 4 - end - if @index >= @character_table.length - @index -= @character_table.length - end - end - end - # If left directional button is pushed + if @index >= @table_size + # Cursor is positioned on OK or mode buttons if Input.repeat?(Input::LEFT) # If directional button pressed down is not a repeat, or # cursor is not positioned on the left edge - if Input.trigger?(Input::LEFT) or - @index / @group_size > 0 or @index % GROUP_WIDTH > 0 - # Move cursor to left + old_slot = mode_button_slot + if Input.trigger?(Input::LEFT) || old_slot != 0 $game_system.se_play($data_system.cursor_se) - if @index % GROUP_WIDTH > 0 + if old_slot == 0 + @index = @table_size + @table_width - 1 + else + loop do + @index -= 1 + break if old_slot != mode_button_slot + end + end + end + end + if Input.repeat?(Input::RIGHT) + # If directional button pressed down is not a repeat, or + # cursor is not positioned on the right edge + old_slot = mode_button_slot + if Input.trigger?(Input::RIGHT) || old_slot != -1 + $game_system.se_play($data_system.cursor_se) + if old_slot == -1 + @index = @table_size + else + loop do + @index += 1 + break if old_slot != mode_button_slot + end + end + end + end + if Input.trigger?(Input::DOWN) + $game_system.se_play($data_system.cursor_se) + @index -= @table_size + end + if Input.repeat?(Input::UP) + $game_system.se_play($data_system.cursor_se) + @index -= @table_width + end + else + # Cursor is not positioned on OK or mode buttons + if Input.repeat?(Input::RIGHT) + # If directional button pressed down is not a repeat, or + # cursor is not positioned on the right edge + if Input.trigger?(Input::RIGHT) || @index % @table_width < @table_width - 1 + $game_system.se_play($data_system.cursor_se) + if @index % @table_width < @table_width - 1 + @index += 1 + else + @index -= @table_width - 1 + end + end + end + if Input.repeat?(Input::LEFT) + # If directional button pressed down is not a repeat, or + # cursor is not positioned on the left edge + if Input.trigger?(Input::LEFT) || @index % @table_width > 0 + $game_system.se_play($data_system.cursor_se) + if @index % @table_width > 0 @index -= 1 else - @index -= @group_size - 4 - end - if @index < 0 - @index += @character_table.length + @index += @table_width - 1 end end end - # If down directional button is pushed if Input.repeat?(Input::DOWN) - # Move cursor down $game_system.se_play($data_system.cursor_se) - if @index % @group_size < @group_size - GROUP_WIDTH - @index += GROUP_WIDTH - else - @index += @character_table.length - (@group_size - GROUP_WIDTH) - end + @index += @table_width end - # If up directional button is pushed if Input.repeat?(Input::UP) # If directional button pressed down is not a repeat, or # cursor is not positioned on the upper edge - if Input.trigger?(Input::UP) or @index % @group_size >= GROUP_WIDTH - # Move cursor up + if Input.trigger?(Input::UP) || @index >= @table_width $game_system.se_play($data_system.cursor_se) - if @index % @group_size >= GROUP_WIDTH - @index -= GROUP_WIDTH + if @index >= @table_width + @index -= @table_width else - @index += @character_table.length + @index += @table_size end end end diff --git a/scripts/_scripts.txt b/scripts/_scripts.txt index 4d56a0a..8087f46 100644 --- a/scripts/_scripts.txt +++ b/scripts/_scripts.txt @@ -100,8 +100,8 @@ Scene_Debug Persistent # Internationalization -i18n_Translator i18n_Language +i18n_English # Data Data_Item diff --git a/scripts/i18n_English.rb b/scripts/i18n_English.rb new file mode 100644 index 0000000..db9382c --- /dev/null +++ b/scripts/i18n_English.rb @@ -0,0 +1,27 @@ +# Default English localization settings +Font.default_name = Language::FONT_WESTERN + +class Language + def self.create_input + input = Window_NameInput.new + input.set_mode_buttons [['Upper', 'Lower']] + input.character_tables = { + [0] => [ # Case: Upper + "A","B","C","D","E","F","G","H","I","J", + "K","L","M","N","O","P","Q","R","S","T", + "U","V","W","X","Y","Z"," ",".",",","-", + "0","1","2","3","4","5","6","7","8","9", + "!","?",'"',"'","/","&","[","]","(",")", + ], + [1] => [ # Case: Lower + "a","b","c","d","e","f","g","h","i","j", + "k","l","m","n","o","p","q","r","s","t", + "u","v","w","x","y","z"," ",".",",","-", + "0","1","2","3","4","5","6","7","8","9", + "!","?",'"',"'","/","&","[","]","(",")", + ], + } + input.table_height = 5 + input.init + end +end diff --git a/scripts/i18n_Japanese.rb b/scripts/i18n_Japanese.rb new file mode 100644 index 0000000..8d446d2 --- /dev/null +++ b/scripts/i18n_Japanese.rb @@ -0,0 +1,35 @@ +Font.default_name = Language::FONT_CJK + +class Language + def self.create_input + input = Window_NameInput.new + input.ok_text = '決定' + input.set_mode_buttons [['かな', 'カナ', '英字']] + input.character_tables = { + [0] => [ # Hiragana + "ー","っ","ぁ","ぱ","ば","だ","ざ","が","わ","ら","や","ま","は","な","た","さ","か","あ", + "~","ゃ","ぃ","ぴ","び","ぢ","じ","ぎ"," ","り"," ","み","ひ","に","ち","し","き","い", + "・","ゅ","ぅ","ぷ","ぶ","づ","ず","ぐ","を","る","ゆ","む","ふ","ぬ","つ","す","く","う", + "=","ょ","ぇ","ぺ","べ","で","ぜ","げ"," ","れ"," ","め","へ","ね","て","せ","け","え", + "☆","ゎ","ぉ","ぽ","ぼ","ど","ぞ","ご","ん","ろ","よ","も","ほ","の","と","そ","こ","お", + ], + [1] => [ # Katakana + "ー","ッ","ァ","パ","バ","ダ","ザ","ガ","ワ","ラ","ヤ","マ","ハ","ナ","タ","サ","カ","ア", + "~","ャ","ィ","ピ","ビ","ヂ","ジ","ギ"," ","リ"," ","ミ","ヒ","ニ","チ","シ","キ","イ", + "・","ュ","ゥ","プ","ブ","ヅ","ズ","グ","ヲ","ル","ユ","ム","フ","ヌ","ツ","ス","ク","ウ", + "=","ョ","ェ","ペ","ベ","デ","ゼ","ゲ"," ","レ"," ","メ","ヘ","ネ","テ","セ","ケ","エ", + "☆","ヮ","ォ","ポ","ボ","ド","ゾ","ゴ","ン","ロ","ヨ","モ","ホ","ノ","ト","ソ","コ","オ", + ], + [2] => [ # Latin + "A","B","C","D","E","F","G","H","I","a","b","c","d","e","f","g","h","i", + "J","K","L","M","N","O","P","Q","R","j","k","l","m","n","o","p","q","r", + "S","T","U","V","W","X","Y","Z"," ","s","t","u","v","w","x","y","z"," ", + "0","1","2","3","4","+","-","=","&","!","?","'",'"',".",",",":",";","$", + "5","6","7","8","9","*","/","#","|","[","]","(",")","<",">","{","}","@", + ], + } + input.index = 17 # Start on あ + input.table_height = 5 + input.init + end +end diff --git a/scripts/i18n_Language.rb b/scripts/i18n_Language.rb index 4571229..8581c12 100644 --- a/scripts/i18n_Language.rb +++ b/scripts/i18n_Language.rb @@ -1,147 +1,61 @@ +# Classes for translating text similar to GNU gettext + +# Translator class: translate text to another language class Language - attr_reader :font - attr_reader :character_table - attr_reader :character_table_height - - def initialize(font, character_table, character_table_height) - @font = font - @character_table = character_table - @character_table_height = character_table_height - end - - def self.get(lc) - return LANGUAGES[lc.full] || LANGUAGES[lc.lang] || LANGUAGES[:en] - end - FONT_WESTERN = 'Terminus (TTF)' FONT_CJK = 'WenQuanYi Micro Hei' - LANGUAGES = { - :en => Language.new( - FONT_WESTERN, [ - "A","B","C","D","E", - "F","G","H","I","J", - "K","L","M","N","O", - "P","Q","R","S","T", - "U","V","W","X","Y", - "Z"," "," "," "," ", - "+","-","*","/","!", - "1","2","3","4","5", + class << self + def set(lc) + @tr = nil + script = nil + [lc.full.to_s, lc.lang.to_s].each do |name| + begin + @tr, script = load_data("Languages/#{name}.rxdata") + break + rescue + end + end + exec(script) if script + Oneshot.set_yes_no(tr('Yes'), tr('No')) + end - "a","b","c","d","e", - "f","g","h","i","j", - "k","l","m","n","o", - "p","q","r","s","t", - "u","v","w","x","y", - "z"," "," "," "," ", - "#","$","%","&","@", - "6","7","8","9","0", - ], 8 - ), - :es => Language.new( - FONT_WESTERN, [ - "A","B","C","D","E", - "F","G","H","I","J", - "K","L","M","N","O", - "P","Q","R","S","T", - "U","V","W","X","Y", - "Z"," ","Ñ","Ü"," ", - "Á","É","Í","Ó","Ú", - "+","-","*","/","!", - "1","2","3","4","5", + # Translate some text + def tr(string) + if @data + @data[Zlib::crc32(string)] || string + else + string + end + end - "a","b","c","d","e", - "f","g","h","i","j", - "k","l","m","n","o", - "p","q","r","s","t", - "u","v","w","x","y", - "z"," ","ñ","ü"," ", - "á","é","í","ó","ú", - "¡","#","%","&","@", - "6","7","8","9","0", - ], 9 - ), - :ja => Language.new( - FONT_CJK, [ - "あ","い","う","え","お", - "か","き","く","け","こ", - "さ","し","す","せ","そ", - "た","ち","つ","て","と", - "な","に","ぬ","ね","の", - "は","ひ","ふ","へ","ほ", - "ま","み","む","め","も", - "や", "","ゆ", "","よ", - "ら","り","る","れ","ろ", - - "わ", "","を", "","ん", - "が","ぎ","ぐ","げ","ご", - "ざ","じ","ず","ぜ","ぞ", - "だ","ぢ","づ","で","ど", - "ば","び","ぶ","べ","ぼ", - "ぱ","ぴ","ぷ","ぺ","ぽ", - "ゃ","ゅ","ょ","っ","ゎ", - "ぁ","ぃ","ぅ","ぇ","ぉ", - "ー","・", "", "", "", - - "ア","イ","ウ","エ","オ", - "カ","キ","ク","ケ","コ", - "サ","シ","ス","セ","ソ", - "タ","チ","ツ","テ","ト", - "ナ","ニ","ヌ","ネ","ノ", - "ハ","ヒ","フ","ヘ","ホ", - "マ","ミ","ム","メ","モ", - "ヤ", "","ユ", "","ヨ", - "ラ","リ","ル","レ","ロ", - - "ワ", "","ヲ", "","ン", - "ガ","ギ","グ","ゲ","ゴ", - "ザ","ジ","ズ","ゼ","ゾ", - "ダ","ヂ","ヅ","デ","ド", - "バ","ビ","ブ","ベ","ボ", - "パ","ピ","プ","ペ","ポ", - "ャ","ュ","ョ","ッ","ヮ", - "ァ","ィ","ゥ","ェ","ォ", - "ー","・","ヴ", "", "", - ], 9 - ), - :ko => Language.new( - FONT_CJK, [ - "가","개","갸","거","게", - "겨","고","교","구","규", - "그","기","나","내","냐", - "너","네","녀","노","뇨", - "누","뉴","느","니","다", - "대","댜","더","데","뎌", - "도","됴","두","듀","드", - "디","라","래","랴","러", - - "레","려","로","료","루", - "류","르","리","마","매", - "먀","머","메","며","모", - "묘","무","뮤","므","미", - "바","배","뱌","버","베", - "벼","보","뵤","부","뷰", - "브","비","아","애","야", - "어","에","여","오","요", - - "우","유","으","이","자", - "재","쟈","저","제","져", - "조","죠","주","쥬","즈", - "지","차","채","챠","처", - "체","쳐","초","쵸","추", - "츄","츠","치","카","캐", - "캬","커","케","켜","코", - "쿄","쿠","큐","타","태", - - "탸","터","테","텨","토", - "툐","투","튜","트","티", - "파","패","퍄","퍼","페", - "펴","포","표","푸","퓨", - "프","피","하","해","햐", - "허","헤","혀","호","효", - "후","휴","흐","히","", - "","","","","", - ], 8 - ), - } + # Turn all database items into translatable strings + def initialize_database + $data_actors.each do |i| + i.name = TrString.new(i.name) if i && !i.name.empty? + end + $data_items.each do |i| + if i && !i.name.empty? + i.name = TrString.new(i.name) + i.description = TrString.new(i.description) + end + end + end + end +end + +# Translatable string +class TrString + def initialize(str) + @str = str + end + + def to_str + Language.tr(@str) + end + alias :to_s :to_str +end + +def tr(text) + TrString.new(text) end diff --git a/scripts/i18n_Translator.rb b/scripts/i18n_Translator.rb deleted file mode 100644 index 4a814a2..0000000 --- a/scripts/i18n_Translator.rb +++ /dev/null @@ -1,87 +0,0 @@ -# Classes for translating text similar to GNU gettext - -# Translation class: contains translation data -class Translation - attr_reader :events - attr_reader :scripts - attr_reader :actors - attr_reader :items -end - -# Translator class: translate text to another language -class Translator - # Create Translator object - def initialize(lc) - @data = nil - [lc.full.to_s, lc.lang.to_s].each do |name| - begin - @data = load_data("Langauges/#{name}.rxdata") - break - rescue - end - end - end - - # Translate all database items - def translate_database - $data_actors.each do |i| - i.name = actor(i.name) if i && !i.name.empty? - end - $data_items.each do |i| - i.name, i.description = item(i.name, i.description) if i && !i.name.empty? - end - end - - # Translate script text - def script(name, text) - if @data == nil - return text - else - return @data.scripts["#{name}/#{text}"] || text - end - end - - # Translate text from event - def event(name, text) - if @data == nil - return text - else - return @data.events["#{name}/#{text}"] || text - end - end - - private - # Translate Actor name - def actor(name) - if @data == nil - return name - else - return @data.actors[name] || name - end - end - - # Translate Item name (and description) - def item(name, description) - if @data == nil - return [name, description] - else - return @data.items[name] || [name, description] - end - end -end - -# Translatable string -class TrString - def initialize(str) - @str = str - end - - def to_str - @str - end - alias :to_s :to_str -end - -def tr(text) - TrString.new(text) -end diff --git a/src/sharedstate.cpp b/src/sharedstate.cpp index f46cffb..dbfbe30 100644 --- a/src/sharedstate.cpp +++ b/src/sharedstate.cpp @@ -49,19 +49,6 @@ SharedState *SharedState::instance = 0; int SharedState::rgssVersion = 0; static GlobalIBO *_globalIBO = 0; -static const char *gameArchExt() -{ - if (rgssVer == 1) - return ".rgssad"; - else if (rgssVer == 2) - return ".rgss2a"; - else if (rgssVer == 3) - return ".rgss3a"; - - assert(!"unreachable"); - return 0; -} - struct SharedStatePrivate { void *bindingData;