03-02-2008, 06:04 AM
Loading Data from File
Version: 1.0
Version: 1.0
Introduction
This script will allow a scripter to load data from a text file. Great for scripts that require large amounts of data and you don't want to define things using the database or the script editor. The script will catch many different errors while reading from the file (Syntax Errors, Missing } for hashes and Missing ] for arrays) and tells the line(s) and data where the error was found. Also This Tool can load data on multiple lines. And Organizes the information loaded.
Screenshots
Yeah that will help.
Script
Code:
module Trickster
class File_LoadRxdata < File
attr_accessor :line
def format_readline
data = self.readline
@line = data.dup
data = data.split(/\s/)
data.delete("")
return data
end
def requirements(data, required, properties)
for i in required
if data[i].nil? and i < properties.size
s1 = "Error Loading Data"
s2 = "\n#{properties[i]} is undefined"
Kernel.print(s1+s2)
exit
end
end
end
def error_incorrect_name
s1 = "Error Loading Data at Line number #{file.lineno}"
s2 = "\nIncorrect defining name"
s3 = "\nLine data: #{self.line}"
Kernel.print(s1+s2+s3)
exit
end
def error_array(extra)
s1 = "Error Loading Data at Line number#{extra}"
s2 = "\nMissing ']' for Array"
s3 = "\nLine data: #{self.line}"
Kernel.print(s1+s2+s3)
exit
end
def error_hash(extra)
s1 = "Error Loading Data at Line number#{extra}"
s2 = "\nMissing '}' for Hash"
s3 = "\nLine data: #{self.line}"
Kernel.print(s1+s2+s3)
exit
end
def error_syntax(extra)
s1 = "Error Loading Data at Line number#{extra}"
s2 = "\nSyntax Error"
s3 = "\nLine Data: #{self.line}"
Kernel.print(s1+s2+s3)
exit
end
def load_next_line
return false if self.eof?
data = self.format_readline
return true if data == [] or data[0].include?("#")
return data
end
def test_type(data, line, lineno, multi = 0)
# make a copy of the data
temp = data.dup
# set extra text if an error is found
extra = (multi > 0) ? "s #{lineno}-#{lineno+multi}" : " #{lineno}"
if temp == "nil" #If a nil reference
data = nil
elsif temp.slice(0..0) == "[" #if an array
if !temp.include?("]")
self.error_array(extra)
end
begin
data = eval(data)
rescue SyntaxError
self.error_syntax(extra)
end
elsif temp.slice(0..0) == "{" #if a hash
if !temp.include?("}")
self.error_hash(extra)
end
begin
data = eval(data)
rescue SyntaxError
self.error_syntax(extra)
end
elsif test_int(temp) #If a number or "0"
data = data.to_i
end
#else it is a string so just return
return data
end
def test_int(data)
flag = true
for i in 0...data.length
test = data.slice(i..i)
if test == "0" or test.to_i != 0
flag = flag && true
else
flag = false
end
end
return flag
end
end
#loading data from a text file
#inputs: file_name = file name to load
# properties = defining values (see example)
# required = required values to be loaded
# multi_lined = defining values that accept multiple lines (strings only)
#returns: an array with the data from text file
def self.load_data_from_txt(file_name, properties, required = [0], multi_lined = [])
# Initialize local variables
final_data = []
data_txt = []
index = 1
# Load File
file = Trickster::File_LoadRxdata.open(file_name)
# Loop until End of File (EOF)
until file.eof?
# Get line data
data = file.format_readline
# Get Line
line = file.line
# Next if no data or commented line
next if data == [] or data[0].include?("#")
# Get id from the properties
id = properties.index(data[0])
# If a new id
if id == 0 and data_txt != []
# Check requirements and return error if not fulfilled
file.requirements(data_txt, required, properties)
# Finished reading a piece of data
final_data[index] = data_txt.dup
# Increase index and reset data
index += 1
data_txt = []
elsif id == nil
# Incorrent Defining name error message
file.error_incorrect_name
end
# Remove defining name and join together
data.delete_at(0)
data = data.join(' ')
# Get line number
lineno = file.lineno
# Start multi line information checking
multi = 1
if multi_lined.include?(id)
# Load next line
next_line = file.load_next_line
# Get first data
first = next_line.is_a?(Array) ? next_line[0] : ""
# Reset flag
flag = false
# While an invalid property and the file is not eof? or data loaded
while (properties.index(first) == nil and (next_line != false or next_line.is_a?(Array)))
# While was excuted once
flag = true
position = file.pos
# add to data if an array
if next_line.is_a?(Array)
# Get property data
first = next_line[0]
if properties.index(first) == nil
data += ' ' + next_line.join(' ')
end
end
# Load next line and reset first
next_line = file.load_next_line
first = ""
# increase multi line count
multi += 1
# break if file.eof? continue if line was a comment
break if next_line == false
next if next_line == true
first = next_line[0]
end
if flag
file.pos = position
end
if next_line.is_a?(Array)
if properties.index(first) == nil
data += next_line.join(' ')
end
end
end
data = file.test_type(data, line, lineno, multi)
data_txt[id] = data
end
# Reached End of File Get last data if any
if data_txt != []
# Check requirements and return error if not fulfilled
file.requirements(data_txt, required, properties)
# Finished reading a piece of data
final_data[index] = data_txt
# Increase index and reset data
index += 1
data_txt = []
end
# return all data compacted
return final_data.compact
end
end
Instructions
To call just use use
data = Trickster.load_data_from_txt(file, properties[, required, multi_lined])
file is the file to load for reading
properties are the defining names of the data you want to load
required is the names that must be defined (by default the first item is required)
multi_lined are the defining names whose data can be defined on multiple lines
An Example Call
Code:
Scene_Title method main additions
load_mission_info
if @load_mission
if Mission::Constants::SAVE_DATA
save_data($data_missions, "Data/Missions2.rxdata")
end
else
$data_missions = load_data("Data/Missions2.rxdata")
end
def load_mission_info
properties = []
properties[0] = "id"
properties[1] = "name"
properties[2] = "icon"
properties[3] = "cost"
properties[4] = "rank"
properties[5] = "switch"
properties[6] = "area"
properties[7] = "skills"
properties[8] = "items"
properties[9] = "mission"
properties[10] = "random"
properties[11] = "cancel"
properties[12] = "penalty"
properties[13] = "reward"
properties[14] = "description"
filename = "Data\\Missions.rxdata"
@load_mission = true
begin
$data_missions = [nil]
missions = Trickster.load_data_from_txt(filename,properties,[0,1],[14])
for mission in missions
$data_missions[mission[0]] = RPG::Mission.new(mission)
end
rescue
#project is encrypted the file can't be found
@load_mission = false
end
end
and the corresponding text file will look like this
Code:
id 1
name Ghosts!?!
icon battle_icon
cost 200
rank 1
switch 1
description A C[C0C0C0]GhostC[N] has been spotted near the lake can someone please
get rid of him. Meet me outside this building if you take this request.
N[]T[]~Some random guy
area [1]
skills nil
items nil
mission nil
random nil
cancel false
penalty nil
reward {'gold' => 500,'combat' => 10, 'weapons' => 2}
id 2
name Help Me!!
icon note_icon
cost 150
rank 1
switch 2
area [1]
skills {'negotiate' => 1}
items nil
mission [1]
random nil
cancel true
penalty {'gold' => 50}
reward {'negotiate' => 3, 'weapons' => 2, 'items' => 3}
description Can someone please buy this item off of me. My shop is going out of business
and I need the money to feed my family. Meet me near the river if you choose to take this request.
N[]T[]~Shop owner
FAQ
Note: Permission granted by Trickster to post:
Quote:And if you post what you have now of my stuff then you don't have the latest versions. I'm too lazy/busy to post stuff.As this is his material, it is deletable upon his request. Due to his current absense, no support is available. Please do not PM or eMail him for support.
Compatibility
Compatible with everything
Terms and Conditions
Hey, I posted this publicly. You can use it. What do you expect? But if you do use it, I do expect you to spell my name correctly in your game. And yes you can use it in commercial games too.