From 2962944cab2b14042ed47e21b0760a9e1111b493 Mon Sep 17 00:00:00 2001 From: Maruno17 Date: Sun, 11 Sep 2022 19:07:47 +0100 Subject: [PATCH] Redesigned phone.txt (old format isn't supported), added support for contact-specific phone messages, added more phone message components --- Data/Scripts/010_Data/001_GameData.rb | 1 + .../010_Data/002_PBS data/001_MiscPBSData.rb | 13 --- .../002_PBS data/002_PhoneDatabase.rb | 24 ----- .../010_Data/002_PBS data/019_PhoneMessage.rb | 96 +++++++++++++++++++ Data/Scripts/013_Items/004_Item_Phone.rb | 59 ++++++++---- Data/Scripts/021_Compiler/001_Compiler.rb | 2 +- .../021_Compiler/002_Compiler_CompilePBS.rb | 90 +++++++++++------ .../021_Compiler/003_Compiler_WritePBS.rb | 42 ++++---- PBS/phone.txt | 74 ++++++++------ 9 files changed, 262 insertions(+), 139 deletions(-) delete mode 100644 Data/Scripts/010_Data/002_PBS data/002_PhoneDatabase.rb create mode 100644 Data/Scripts/010_Data/002_PBS data/019_PhoneMessage.rb diff --git a/Data/Scripts/010_Data/001_GameData.rb b/Data/Scripts/010_Data/001_GameData.rb index 97daec1ab..a8c412c85 100644 --- a/Data/Scripts/010_Data/001_GameData.rb +++ b/Data/Scripts/010_Data/001_GameData.rb @@ -240,5 +240,6 @@ module GameData Metadata.load PlayerMetadata.load MapMetadata.load + PhoneMessage.load end end diff --git a/Data/Scripts/010_Data/002_PBS data/001_MiscPBSData.rb b/Data/Scripts/010_Data/002_PBS data/001_MiscPBSData.rb index 3d37cfbe9..8b5da65b0 100644 --- a/Data/Scripts/010_Data/002_PBS data/001_MiscPBSData.rb +++ b/Data/Scripts/010_Data/002_PBS data/001_MiscPBSData.rb @@ -3,7 +3,6 @@ #=============================================================================== class Game_Temp attr_accessor :town_map_data - attr_accessor :phone_messages_data attr_accessor :regional_dexes_data attr_accessor :battle_animations_data attr_accessor :move_to_battle_animation_data @@ -13,7 +12,6 @@ end def pbClearData if $game_temp $game_temp.town_map_data = nil - $game_temp.phone_messages_data = nil $game_temp.regional_dexes_data = nil $game_temp.battle_animations_data = nil $game_temp.move_to_battle_animation_data = nil @@ -37,17 +35,6 @@ def pbLoadTownMapData return $game_temp.town_map_data end -#=============================================================================== -# Method to get phone call data. -#=============================================================================== -def pbLoadPhoneData - $game_temp = Game_Temp.new if !$game_temp - if !$game_temp.phone_messages_data && pbRgssExists?("Data/phone.dat") - $game_temp.phone_messages_data = load_data("Data/phone.dat") - end - return $game_temp.phone_messages_data -end - #=============================================================================== # Method to get Regional Dexes data. #=============================================================================== diff --git a/Data/Scripts/010_Data/002_PBS data/002_PhoneDatabase.rb b/Data/Scripts/010_Data/002_PBS data/002_PhoneDatabase.rb deleted file mode 100644 index ab8cd7912..000000000 --- a/Data/Scripts/010_Data/002_PBS data/002_PhoneDatabase.rb +++ /dev/null @@ -1,24 +0,0 @@ -#=============================================================================== -# Phone data -#=============================================================================== -class PhoneDatabase - attr_accessor :generics - attr_accessor :greetings - attr_accessor :greetingsMorning - attr_accessor :greetingsEvening - attr_accessor :bodies1 - attr_accessor :bodies2 - attr_accessor :battleRequests - attr_accessor :trainers - - def initialize - @generics = [] - @greetings = [] - @greetingsMorning = [] - @greetingsEvening = [] - @bodies1 = [] - @bodies2 = [] - @battleRequests = [] - @trainers = [] - end -end diff --git a/Data/Scripts/010_Data/002_PBS data/019_PhoneMessage.rb b/Data/Scripts/010_Data/002_PBS data/019_PhoneMessage.rb new file mode 100644 index 000000000..9f90c3223 --- /dev/null +++ b/Data/Scripts/010_Data/002_PBS data/019_PhoneMessage.rb @@ -0,0 +1,96 @@ +module GameData + class PhoneMessage + attr_reader :id + attr_reader :trainer_type, :real_name, :version + attr_reader :intro, :intro_morning, :intro_afternoon, :intro_evening + attr_reader :body, :body1, :body2 + attr_reader :battle_request, :battle_remind + attr_reader :end + + DATA = {} + DATA_FILENAME = "phone.dat" + + SCHEMA = { + "Intro" => [:intro, "q"], + "IntroMorning" => [:intro_morning, "q"], + "IntroAfternoon" => [:intro_afternoon, "q"], + "IntroEvening" => [:intro_evening, "q"], + "Body" => [:body, "q"], + "Body1" => [:body1, "q"], + "Body2" => [:body2, "q"], + "BattleRequest" => [:battle_request, "q"], + "BattleRemind" => [:battle_remind, "q"], + "End" => [:end, "q"] + } + + extend ClassMethodsSymbols + include InstanceMethods + + # @param tr_type [Symbol, String] + # @param tr_name [String] + # @param tr_version [Integer, nil] + # @return [Boolean] whether the given other is defined as a self + def self.exists?(tr_type, tr_name, tr_version = 0) + validate tr_type => [Symbol, String] + validate tr_name => [String] + key = [tr_type.to_sym, tr_name, tr_version] + return !self::DATA[key].nil? + end + + # @param tr_type [Symbol, String] + # @param tr_name [String] + # @param tr_version [Integer, nil] + # @return [self] + def self.get(tr_type, tr_name, tr_version = 0) + validate tr_type => [Symbol, String] + validate tr_name => [String] + key = [tr_type.to_sym, tr_name, tr_version] + raise "Phone messages not found for #{tr_type} #{tr_name} #{tr_version}." unless self::DATA.has_key?(key) + return self::DATA[key] + end + + # @param tr_type [Symbol, String] + # @param tr_name [String] + # @param tr_version [Integer, nil] + # @return [self, nil] + def self.try_get(tr_type, tr_name, tr_version = 0) + validate tr_type => [Symbol, String] + validate tr_name => [String] + key = [tr_type.to_sym, tr_name, tr_version] + return (self::DATA.has_key?(key)) ? self::DATA[key] : nil + end + + def initialize(hash) + @id = hash[:id] + @trainer_type = hash[:trainer_type] + @real_name = hash[:name] + @version = hash[:version] || 0 + @intro = hash[:intro] + @intro_morning = hash[:intro_morning] + @intro_afternoon = hash[:intro_afternoon] + @intro_evening = hash[:intro_evening] + @body = hash[:body] + @body1 = hash[:body1] + @body2 = hash[:body2] + @battle_request = hash[:battle_request] + @battle_remind = hash[:battle_remind] + @end = hash[:end] + end + + def property_from_string(str) + case str + when "Intro" then return @intro + when "IntroMorning" then return @intro_morning + when "IntroAfternoon" then return @intro_afternoon + when "IntroEvening" then return @intro_evening + when "Body" then return @body + when "Body1" then return @body1 + when "Body2" then return @body2 + when "BattleRequest" then return @battle_request + when "BattleRemind" then return @battle_remind + when "End" then return @end + end + return nil + end + end +end diff --git a/Data/Scripts/013_Items/004_Item_Phone.rb b/Data/Scripts/013_Items/004_Item_Phone.rb index b41b56233..7d7653ebf 100644 --- a/Data/Scripts/013_Items/004_Item_Phone.rb +++ b/Data/Scripts/013_Items/004_Item_Phone.rb @@ -469,36 +469,59 @@ class Phone def generate_trainer_dialogue(contact) validate contact => Phone::Contact + # Get the set of messages to be used by the contact + messages = GameData::PhoneMessage.try_get(contact.trainer_type, contact.name, contact.version) + messages = GameData::PhoneMessage.try_get(contact.trainer_type, contact.name, contact.start_version) if !messages + messages = GameData::PhoneMessage::DATA["default"] if !messages + # Create lambda for choosing a random message and translating it get_random_message = lambda do |messages| + return "" if !messages msg = messages.sample return "" if !msg return pbGetMessageFromHash(MessageTypes::PhoneMessages, msg) end - phone_data = pbLoadPhoneData # Choose random greeting depending on time of day - ret = get_random_message.call(phone_data.greetings) + ret = get_random_message.call(messages.intro) time = pbGetTimeNow if PBDayNight.isMorning?(time) - modcall = get_random_message.call(phone_data.greetingsMorning) - ret = modcall if !nil_or_empty?(modcall) + mod_call = get_random_message.call(messages.intro_morning) + ret = mod_call if !nil_or_empty?(mod_call) + elsif PBDayNight.isAfternoon?(time) + mod_call = get_random_message.call(messages.intro_afternoon) + ret = mod_call if !nil_or_empty?(mod_call) elsif PBDayNight.isEvening?(time) - modcall = get_random_message.call(phone_data.greetingsEvening) - ret = modcall if !nil_or_empty?(modcall) + mod_call = get_random_message.call(messages.intro_evening) + ret = mod_call if !nil_or_empty?(mod_call) end ret += "\\m" - if Phone.rematches_enabled && (contact.rematch_flag == 1 || - (contact.rematch_flag == 2 && rand(100) < 50)) - # If ready for rematch, tell the player (50% chance to remind the player) - ret += get_random_message.call(phone_data.battleRequests) - contact.rematch_flag = 2 # Ready for rematch and told player - elsif rand(100) < 75 - # Choose random body - ret += get_random_message.call(phone_data.bodies1) - ret += "\\m" - ret += get_random_message.call(phone_data.bodies2) + # Choose main message set + if Phone.rematches_enabled && contact.rematch_flag > 0 + # Trainer is ready for a rematch, so tell/remind the player + if contact.rematch_flag == 1 # Tell the player + ret += get_random_message.call(messages.battle_request) + contact.rematch_flag = 2 # Ready for rematch and told player + elsif contact.rematch_flag == 2 # Remind the player + if messages.battle_remind + ret += get_random_message.call(messages.battle_remind) + else + ret += get_random_message.call(messages.battle_request) + end + end else - # Choose random generic - ret += get_random_message.call(phone_data.generics) + # Standard messages + if messages.body1 && messages.body2 && (!messages.body || rand(100) < 75) + echoln messages.body2 + # Choose random pair of body messages + ret += get_random_message.call(messages.body1) + ret += "\\m" + ret += get_random_message.call(messages.body2) + else + # Choose random full body message + ret += get_random_message.call(messages.body) + end + # Choose end message + mod_call = get_random_message.call(messages.end) + ret += "\\m" + mod_call if !nil_or_empty?(mod_call) end return ret end diff --git a/Data/Scripts/021_Compiler/001_Compiler.rb b/Data/Scripts/021_Compiler/001_Compiler.rb index 40e7d5f08..b467925e6 100644 --- a/Data/Scripts/021_Compiler/001_Compiler.rb +++ b/Data/Scripts/021_Compiler/001_Compiler.rb @@ -757,7 +757,6 @@ module Compiler modify_pbs_file_contents_before_compiling compile_town_map compile_connections - compile_phone compile_types compile_abilities compile_moves # Depends on Type @@ -775,6 +774,7 @@ module Compiler compile_trainer_lists # Depends on TrainerType compile_metadata # Depends on TrainerType compile_map_metadata + compile_phone # Depends on TrainerType end def compile_all(mustCompile) diff --git a/Data/Scripts/021_Compiler/002_Compiler_CompilePBS.rb b/Data/Scripts/021_Compiler/002_Compiler_CompilePBS.rb index ad62d1e3f..2267f325b 100644 --- a/Data/Scripts/021_Compiler/002_Compiler_CompilePBS.rb +++ b/Data/Scripts/021_Compiler/002_Compiler_CompilePBS.rb @@ -102,37 +102,69 @@ module Compiler def compile_phone(path = "PBS/phone.txt") return if !safeExists?(path) compile_pbs_file_message_start(path) - database = PhoneDatabase.new - sections = [] - File.open(path, "rb") { |f| - pbEachSection(f) { |section, name| - case name - when "" - database.generics = section - sections.concat(section) - when "" - database.battleRequests = section - sections.concat(section) - when "" - database.greetingsMorning = section - sections.concat(section) - when "" - database.greetingsEvening = section - sections.concat(section) - when "" - database.greetings = section - sections.concat(section) - when "" - database.bodies1 = section - sections.concat(section) - when "" - database.bodies2 = section - sections.concat(section) + GameData::PhoneMessage::DATA.clear + schema = GameData::PhoneMessage::SCHEMA + messages = [] + contact_hash = nil + # Read each line of phone.txt at a time and compile it as a contact property + idx = 0 + pbCompilerEachPreppedLine(path) { |line, line_no| + echo "." if idx % 50 == 0 + idx += 1 + Graphics.update if idx % 250 == 0 + if line[/^\s*\[\s*(.+)\s*\]\s*$/] + # New section [trainer_type, name] or [trainer_type, name, version] + if contact_hash + # Add contact's data to records + if contact_hash[:trainer_type] == "default" + contact_hash[:id] = contact_hash[:trainer_type] + else + contact_hash[:id] = [contact_hash[:trainer_type], contact_hash[:name], contact_hash[:version]] + end + GameData::PhoneMessage.register(contact_hash) end - } + # Construct contact hash + header = $~[1] + if header.strip.downcase == "default" + contact_hash = { + :trainer_type => "default" + } + else + line_data = pbGetCsvRecord($~[1], line_no, [0, "esU", :TrainerType]) + contact_hash = { + :trainer_type => line_data[0], + :name => line_data[1], + :version => line_data[2] || 0 + } + end + elsif line[/^\s*(\w+)\s*=\s*(.*)$/] + # XXX=YYY lines + if !contact_hash + raise _INTL("Expected a section at the beginning of the file.\r\n{1}", FileLineData.linereport) + end + property_name = $~[1] + line_schema = schema[property_name] + next if !line_schema + property_value = pbGetCsvRecord($~[2], line_no, line_schema) + # Record XXX=YYY setting + contact_hash[line_schema[0]] ||= [] + contact_hash[line_schema[0]].push(property_value) + messages.push(property_value) + end } - MessageTypes.setMessagesAsHash(MessageTypes::PhoneMessages, sections) - save_data(database, "Data/phone.dat") + # Add last contact's data to records + if contact_hash + # Add contact's data to records + if contact_hash[:trainer_type] == "default" + contact_hash[:id] = contact_hash[:trainer_type] + else + contact_hash[:id] = [contact_hash[:trainer_type], contact_hash[:name], contact_hash[:version]] + end + GameData::PhoneMessage.register(contact_hash) + end + # Save all data + GameData::PhoneMessage.save + MessageTypes.setMessagesAsHash(MessageTypes::PhoneMessages, messages) process_pbs_file_message_end end diff --git a/Data/Scripts/021_Compiler/003_Compiler_WritePBS.rb b/Data/Scripts/021_Compiler/003_Compiler_WritePBS.rb index b206e8ffa..cba177671 100644 --- a/Data/Scripts/021_Compiler/003_Compiler_WritePBS.rb +++ b/Data/Scripts/021_Compiler/003_Compiler_WritePBS.rb @@ -103,32 +103,26 @@ module Compiler # Save phone messages to PBS file #============================================================================= def write_phone(path = "PBS/phone.txt") - data = load_data("Data/phone.dat") rescue nil - return if !data write_pbs_file_message_start(path) + keys = GameData::PhoneMessage::SCHEMA.keys File.open(path, "wb") { |f| add_PBS_header_to_file(f) - f.write("\#-------------------------------\r\n") - f.write("[]\r\n") - f.write(data.generics.join("\r\n") + "\r\n") - f.write("\#-------------------------------\r\n") - f.write("[]\r\n") - f.write(data.battleRequests.join("\r\n") + "\r\n") - f.write("\#-------------------------------\r\n") - f.write("[]\r\n") - f.write(data.greetingsMorning.join("\r\n") + "\r\n") - f.write("\#-------------------------------\r\n") - f.write("[]\r\n") - f.write(data.greetingsEvening.join("\r\n") + "\r\n") - f.write("\#-------------------------------\r\n") - f.write("[]\r\n") - f.write(data.greetings.join("\r\n") + "\r\n") - f.write("\#-------------------------------\r\n") - f.write("[]\r\n") - f.write(data.bodies1.join("\r\n") + "\r\n") - f.write("\#-------------------------------\r\n") - f.write("[]\r\n") - f.write(data.bodies2.join("\r\n") + "\r\n") + # Write message sets + GameData::PhoneMessage.each do |contact| + f.write("\#-------------------------------\r\n") + if contact.id == "default" + f.write("[Default]\r\n") + elsif contact.version > 0 + f.write(sprintf("[%s,%s,%d]\r\n", contact.trainer_type, contact.real_name, contact.version)) + else + f.write(sprintf("[%s,%s]\r\n", contact.trainer_type, contact.real_name)) + end + keys.each do |key| + msgs = contact.property_from_string(key) + next if !msgs || msgs.length == 0 + msgs.each { |msg| f.write(key + " = " + msg + "\r\n") } + end + end } process_pbs_file_message_end end @@ -886,7 +880,6 @@ module Compiler Console.echo_h1 _INTL("Writing all PBS files") write_town_map write_connections - write_phone write_types write_abilities write_moves @@ -904,6 +897,7 @@ module Compiler write_trainer_lists write_metadata write_map_metadata + write_phone echoln "" Console.echo_h2("Successfully rewrote all PBS files", text: :green) end diff --git a/PBS/phone.txt b/PBS/phone.txt index 226a306f8..9c8344271 100644 --- a/PBS/phone.txt +++ b/PBS/phone.txt @@ -1,34 +1,48 @@ # See the documentation on the wiki to learn how to edit this file. #------------------------------- -[] -How are your Pokémon doing?\mMy \TP's really energetic. It's a handful!\mOh yeah, I managed to beat a tough \TE.\mI need to make my party stronger. -My \TP's looking really awesome.\mI wish I could show you.\mHey, listen! I almost caught a \TE the other day.\mOh, it was sooooooo close, too! +[Default] +Intro = Hello. This is \TN. +Intro = Good day, \PN! Hi. This is \TN. +Intro = How are you doing? \PN, howdy! This is \TN. Isn't it nice out? +Intro = \PN, good day! It's me, \TN. Got a minute? +Intro = Hello, \PN. This is \TN. How are things? +IntroMorning = Good morning, \PN. This is \TN. Did I wake you? +IntroAfternoon = Good afternoon, \PN! It's \TN here. +IntroEvening = \PN, good evening! Hi. This is \TN. +Body = How are your Pokémon doing?\mMy \TP's really energetic. It's a handful!\mOh yeah, I managed to beat a tough \TE.\mI need to make my party stronger. +Body = My \TP's looking really awesome. I wish I could show you.\mHey, listen! I almost caught a \TE the other day.\mOh, it was sooooooo close, too! +Body1 = How are your Pokémon doing?\mMy \TP's really energetic. It's a handful! +Body1 = How are your Pokémon doing?\mI always keep my \TP in top shape by going to Pokémon Centers. +Body1 = My \TP's looking really awesome. I wish I could show you. +Body1 = I dressed my \TP and it looks even cuter than before. +Body2 = Oh yeah, I managed to beat a tough \TE.\mI need to make my party stronger. +Body2 = You have to hear this! I battled \TE the other day.\mIt was easy! I had a type advantage. +Body2 = Hey, listen! I almost caught \TE the other day.\mOh, it was sooooooo close, too! +Body2 = Guess what happened the other day. I missed catching \TE again.\mMaybe I'm not very good at this. +BattleRequest = Want to battle? It's not going to be a repeat of the last time we met.\mI'll be waiting for you around \TM. +BattleRequest = Do you want to battle? I'm going to win this time!\mI'll be waiting for you around \TM.\mLook for me, OK? My \TP will be expecting you. #------------------------------- -[] -Want to battle? It's not going to be a repeat of the last time we met.\mI'll be waiting for you around \TM. -Do you want to battle? I'm going to win this time!\mI'll be waiting for you around \TM.\mLook for me, OK? My \TP will be expecting you. +[CAMPER,Jeff] +Intro = Hello. This is \TN...\mHow's it going, \PN? +Body1 = My \TP is looking more and more like me. It's getting cuter! +Body2 = And you know? Now we can KO \TE easily.\mI should challenge the Cedolan Gym. +Body2 = And you know? We just failed to beat \TE by a tiny margin.\mI'm guessing my Pokémon's levels aren't high enough yet... +BattleRequest = You must be a lot better now, huh?\mHow about showing me your technique in a real battle with me?\mI'll be waiting on \TM. +BattleReminder = Where are you? Let’s have our battle soon!\mI'll be waiting on \TM. +End = See you later! #------------------------------- -[] -Good morning, \PN.\mThis is \TN. Did I wake you? -#------------------------------- -[] -\PN, good evening! Hi.\mThis is \TN. -#------------------------------- -[] -Hello. This is \TN. -Good day, \PN! Hi. This is \TN. -How are you doing? \PN, howdy! This is \TN. Isn't it nice out? -\PN, good day! It's me, \TN. Got a minute? -Hello, \PN. This is \TN. How are things? -#------------------------------- -[] -How are your Pokémon doing?\mMy \TP's really energetic. It's a handful! -How are your Pokémon doing?\mI always keep my \TP in top shape by going to Pokémon Centers. -My \TP's looking really awesome. I wish I could show you. -I dressed my \TP and it looks even cuter than before. -#------------------------------- -[] -Oh yeah, I managed to beat a tough \TE.\mI need to make my party stronger. -You have to hear this! I battled \TE the other day.\mIt was easy! I had a type advantage. -Hey, listen! I almost caught \TE the other day.\mOh, it was sooooooo close, too! -Guess what happened the other day. I missed catching \TE again.\mMaybe I'm not very good at this. +[PICNICKER,Susie] +Intro = This is \TN! +Intro = Hi, this is \TN! +IntroMorning = This is \TN! Good morning, \PN! +IntroMorning = Hi, this is \TN! Good morning, \PN! +IntroAfternoon = This is \TN! Good afternoon, \PN! +IntroAfternoon = Hi, this is \TN! Good afternoon, \PN! +IntroEvening = This is \TN! Good evening, \PN! +IntroEvening = Hi, this is \TN! Good evening, \PN! +Body1 = My \TP and I are getting more in sync with each other. +Body2 = We battled a wild \TE and managed to beat it in a close match.\mWe’re getting into the groove! +Body2 = But, you know what? I still haven’t caught \TE.\mIt’s getting beyond frustrating... +BattleRequest = Would you be my practice partner again sometime?\mI'll be waiting on \TM...\mCould you take it a little easier on me next time? +BattleReminder = How soon can I expect to see you?\mDon't forget, \TM! +End = Bye! Let’s chat again!