Redesigned phone.txt (old format isn't supported), added support for contact-specific phone messages, added more phone message components

This commit is contained in:
Maruno17
2022-09-11 19:07:47 +01:00
parent 4fcd19e247
commit 2962944cab
9 changed files with 262 additions and 139 deletions

View File

@@ -240,5 +240,6 @@ module GameData
Metadata.load
PlayerMetadata.load
MapMetadata.load
PhoneMessage.load
end
end

View File

@@ -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.
#===============================================================================

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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)

View File

@@ -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 "<Generics>"
database.generics = section
sections.concat(section)
when "<BattleRequests>"
database.battleRequests = section
sections.concat(section)
when "<GreetingsMorning>"
database.greetingsMorning = section
sections.concat(section)
when "<GreetingsEvening>"
database.greetingsEvening = section
sections.concat(section)
when "<Greetings>"
database.greetings = section
sections.concat(section)
when "<Bodies1>"
database.bodies1 = section
sections.concat(section)
when "<Bodies2>"
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

View File

@@ -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("[<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")
# 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