Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #==============================================================================
- # Iavra Game Localization - Core Engine 1.00
- # -----------------------------------------------------------------------------
- # Description:
- # Loads language files for the database and messages modules and manages the
- # current language
- # -----------------------------------------------------------------------------
- # Prerequisites:
- # (optional) Iavra Game.ini Access
- # -----------------------------------------------------------------------------
- # How to Use:
- # To get an set the current language, call the follwoing methods:
- #
- # IAVRA::I18N.language
- # IAVRA::I18N.language=
- #
- # Languages are stored in symbol form, like :en or :de. By default, the script
- # stores the current language in its own file. If "Iavra Game.ini Access" is
- # present, it will be stored in the Game.ini file, instead.
- #
- # Language files are basically Ruby hashes and built like this:
- #
- # {
- # :category =>
- # {
- # # module dependent
- # }
- # }
- #
- # Localized text can be accessed by calling the following method:
- #
- # IAVRA::I18N[category]
- #
- # The language of a file is defined by its name and/or directory.
- # -----------------------------------------------------------------------------
- # Terms of Use:
- # Free to use for both commercial and non-commercial games. Please give credit.
- # -----------------------------------------------------------------------------
- # Credits:
- # Iavra
- # -----------------------------------------------------------------------------
- # Changelog:
- # - 1.00: Release version.
- #==============================================================================
- ($imported ||= {})[:iavra_i18n_core] = true
- #==============================================================================
- # ▼ IAVRA::I18N::CORE
- #==============================================================================
- module IAVRA
- module I18N
- module CORE
- #========================================================================
- # ■ ■ ■ ■ ■ CONFIGURATION ■ ■ ■ ■ ■
- #========================================================================
- #========================================================================
- # Lists all languages, that should be supported by the script.
- #========================================================================
- LANGUAGES = [:en, :de]
- #========================================================================
- # Defines the path, where language files will be loaded from. %s is
- # replaced by one of the entries of LANGUAGES and the whole string is
- # treated as a file glob.
- #========================================================================
- FILE_PATH = "I18N/%s{_*,}.rb"
- #========================================================================
- # This file is used to store the current language. If "Iavra Game.ini
- # Access" is present, the Game.ini file will be used, instead.
- #========================================================================
- PERSISTENCE = "I18N/current.txt"
- #========================================================================
- # Setting this to true will enable deep merging for loaded files, which
- # allows to split categories over multiple files.
- #========================================================================
- DEEP_MERGE = false
- #========================================================================
- # Setting this to true will cause language files to be loaded inside
- # their own thread, which acts as a sandbox. Since the files are read in
- # using eval, they could interact with the rest of your game if this is
- # set to false.
- #========================================================================
- SANDBOX = false
- #========================================================================
- # ■ ■ ■ ■ ■ CONFIGURATION ■ ■ ■ ■ ■
- #========================================================================
- class << self
- attr_accessor :language
- attr_reader :language_map
- end
- #========================================================================
- # Sandbox'ed eval, which runs inside its own thread with $SAFE = 4. This
- # is as close to a sandbox as i can get.
- #========================================================================
- def self.sandbox_eval(data)
- Thread.new{
- $SAFE = 4
- Thread.current[:result] = eval(data)
- }.join[:result]
- end
- #========================================================================
- # Methods for loading and saving the current language
- #========================================================================
- if(($imported ||= {})[:iavra_ini_access])
- def self.load_language
- value = IAVRA::INI.load("i18n", "Language", "-").to_sym
- value == :- ? nil : value
- end
- def self.save_language
- IAVRA::INI.save("i18n", "Language", @language)
- end
- else
- def self.load_language
- File.file?(PERSISTENCE) ? File.open(PERSISTENCE) {|file| file.read.to_sym} : nil
- end
- def self.save_language
- File.open(PERSISTENCE, "w") {|file| file.write(@language.to_s)}
- end
- end
- #========================================================================
- # Loads the current language on game starts. Defaults to the first entry
- # in LANGUAGES, if no saved language can be found.
- #========================================================================
- def self.initialize_current_language
- @language = load_language || (flag = LANGUAGES[0])
- @language = nil if !LANGUAGES.include?(@language)
- save_language if flag
- end
- #========================================================================
- # Loads all language files, either directly or inside a sandbox'ed eval.
- # Afterwards, the files are merged to a hash.
- #========================================================================
- def self.initialize_language_map
- @language_map = Hash[LANGUAGES.map{|lang|
- [lang, Dir[FILE_PATH.gsub("%s", lang.to_s)].map{|name|
- File.open(name) {|f| d = f.read; (SANDBOX ? sandbox_eval(d) : eval(d)) || {}}
- }.inject(DEEP_MERGE ? :iavra_i18n_deep_merge : :merge)]
- }]
- end
- end
- #==========================================================================
- # The initialize method is located outside the CORE module to make it
- # easier for the modules to hook themselves into it.
- #==========================================================================
- def self.initialize
- CORE.initialize_current_language
- CORE.initialize_language_map
- end
- #==========================================================================
- # This is called once at game start and whenever the current language is
- # changed and can be used by modules to perform actions.
- #==========================================================================
- def self.update
- end
- #==========================================================================
- # Getter and setter for the current language
- #==========================================================================
- def self.language
- CORE.language
- end
- def self.language=(lang)
- return if lang.nil?
- return if (sym = lang.to_sym) == language
- return unless CORE::LANGUAGES.include?(sym)
- CORE.language = sym
- CORE.save_language
- update
- end
- #==========================================================================
- # Shortcut method to access localized text
- #==========================================================================
- def self.[](sym)
- (CORE.language_map[language] || {})[sym] || {}
- end
- end
- end
- #==============================================================================
- # ▼ Hash
- #==============================================================================
- class Hash
- #============================================================================
- # recursive deep merge
- #============================================================================
- def iavra_i18n_deep_merge(second)
- merger = proc{|key, v1, v2| Hash === v1 && Hash === v2 ? v1.merge(v2, &merger) : v2}
- self.merge(second, &merger)
- end
- end
- #==============================================================================
- # ▼ DataManager
- #==============================================================================
- module DataManager
- class << self
- alias :iavra_i18n_core_load_database :load_database
- end
- def self.load_database
- iavra_i18n_core_load_database
- IAVRA::I18N.initialize
- IAVRA::I18N.update
- end
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement