This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
Brod8362's profile picture

Reading save data from a file

Started by Brod8362, 20 July 2015 - 03:41 AM
Brod8362 #1
Posted 20 July 2015 - 05:41 AM
Hello,
I have been writing (using a tutorial) code for saving / loading data for my game. I really didn't know what I was doing and just following what the guy wrote. I saved the data fine, and then It came to loading it. I don't know how to do that, and what the tutorial said to do didn't work. Any help?
Also, the error I'm getting is battle:339: attempt to compare nil with number which makes me assume that it didn't properly Read the data. Any help?

Code
Spoiler

function drawHUD()
shell.run("/rom/programs/clear")
img = paintutils.loadImage("/rpg/imgs/btl")
paintutils.drawImage(img,1,1)
term.setBackgroundColor(colors.black)
  term.setCursorPos(1,1)
  print("V 0.5")
  term.setTextColor(colors.green)
  term.setCursorPos(28,1)
  print(XP)
  term.setCursorPos(31,1)
  print("/ 100")
  term.setTextColor(colors.white)
  term.setCursorPos(5,3)
  print(HP)
  term.setCursorPos(8,3)
  print("/")
  term.setCursorPos(9,3)
  print(maxHP)
  term.setTextColor(colors.white)
  term.setCursorPos(16,3)
  print(MP)
  term.setCursorPos(19,3)
  print("/")
  term.setCursorPos(20,3)
  print(maxMP)
  term.setTextColor(colors.yellow)
  term.setCursorPos(43,2)
  print(STATUS)
  term.setCursorPos(28,3)
  term.setTextColor(colors.yellow)
  print("LV")
  term.setCursorPos(31,3)
  print(LV)
  term.setCursorPos(32,9)
  print("Enemy")
  term.setCursorPos(32,10)
	print("HP")
  term.setCursorPos(33,11)
  print(eHP)
  renderXP()
  healthBar()
  magicBar()
  term.setBackgroundColor(colors.black)
  term.setTextColor(colors.white)
  term.setCursorPos(2,15)
end

function playerAction()
local sel = 0
term.setCursorPos(2,15)
print("A - Attack M - Magic")
term.setCursorPos(2,16)
print("I - Items  R - Run")
while true do
local event, key2 = os.pullEvent("key")
if key2 == keys.a then
	attack()
	break
	end
  if key2 == keys.m then
	magic()
	break
	end
  if key2 == keys.i then
	items()
	break
	end
  if key2 == keys.r then
	run()
	break
	end
  if key2 == keys.s then
	stats()
	break
	end
  if key2 == keys.slash then
	saveGame()
	print("Game saved!")
	playerAction()
	end

end
end


function attackEnemy()
local eProtV = math.floor(eDEF/4)
local ebdmg = ATT-eProtV
dmg = math.ceil(ebdmg)
eHP = eHP-dmg
textutils.slowWrite(dmg,25)
end

function enemyAttack()
local ProtV = math.floor(DEF/4)
local bdmg= eATT-ProtV
local eDMG = math.ceil(bdmg)
HP = HP-eDMG
term.setCursorPos(7,4)
term.setTextColor(colors.red)
print(eDMG)
sleep(1)
term.setTextColor(colors.white)
end

function checkWin()
if eHP < 1 then
print("VICTORY")
sleep(3)
XP = XP+5
checkLevelUp()
end
end
function checkLose()
if HP < 1 then
print("LOSS...")
sleep(3)
shell.run("menu")
end
end

function magicList()
print("1) Zap 8MP 2DMG")
print("2) End 0MP 9999DMG")
print("3) Heal Enemy 0MP")
print("4) Return")
select = read()
if select  == "1" then
  mATT = 2
  mpCost = 8
  useMagic()
  checkWin()
  checkLose()
  end
if select == "2" then
mATT=9999
mpCost=0
useMagic()
checkWin()
checkLose()
end
if select == "3" then
eHP = 1
mpCost=0
mATT=0
useMagic()
end
if select == "4" then
playerAction()
else
drawHUD()
magicList()
end
end


function useMagic()
if MP >= mpCost then
mDMG = MAG*mATT
MP = MP - mpCost
eHP = eHP - mDMG
textutils.slowWrite(mDMG,2)
poison()
regen()
enemyAttack()
drawHUD()
checkWin()
checkLose()
playerAction()
else
print("Not Enough MP!")
sleep(3)
drawHUD()
magicList()
end
end

function itemList()
print("1. Healing Potion - Heal 25 HP")
print("2. Magic Potion - Heal 15 MP")
print("3. Poison Potion - Poison yourself")
print("4. Antidote - Remove Status effects")
print("5. Regen Potion - Regen 1 HP per turn")
local choice = read()
if choice == "1" then
HP = HP+25
checkMax()
afterYou()
end
if choice == "2" then
MP = MP+15
checkMax()
afterYou()
end
if choice == "3" then
STATUS = "POISONED"
afterYou()
end
if choice == "4" then
STATUS = "OK"
afterYou()
end
if choice == "5" then
STATUS = "REGEN"
afterYou()
else
drawHUD()
playerAction()
end
end


function afterYou()
enemyAttack()
checkMax()
drawHUD()
playerAction()
end

function checkMax()
if HP > maxHP then
HP = maxHP
end
if MP > maxMP then
MP = maxMP
end
end

function attack()
attackEnemy()
drawHUD()
sleep(1)
enemyAttack()
poison()
regen()
checkMax()
checkWin()
checkLose()
drawHUD()
playerAction()
end

function magic()
magicList()
end

function items()
itemList()
end

function run()
if LV >= eLV then
print("Ran away!")
sleep(3)
shell.exit()
else
print("Failed to run away!")
sleep(2)
drawHUD()
playerAction()
end
end

function stats()
print("HP")
print(HP, "/", maxHP)
print("MP")
print(MP, "/", maxMP)
print("ATT")
print(ATT)
print("DEF")
print(DEF)
print("MAG")
print(MAG)
print("XP")
print(XP, "/ 100")
read()
playerAction()
end

function checkLevelUp()
if XP >= 100 then
print("Level up!")
print(LV)
XP = XP-100
LV = LV+1
print("v")
print(LV)
print("Max HP ",maxHP,"Max MP ",maxMP,"ATT ",ATT,"DEF ",DEF,"MAG ",MAG)
maxHP = maxHP+3
maxMP = maxMP+3
ATT = ATT+2
DEF = DEF+2
MAG = MAG+2
HP = maxHP
MP = maxMP
sleep(2)
print("Max HP ",maxHP,"Max MP ",maxMP,"ATT ",ATT,"DEF ",DEF,"MAG ",MAG)
sleep(2)
print("Boost Which Stat?")
print("1) Max HP 2) Max MP 3) ATT 4) DEF 5) MAG")
input = read()
if input == "1" then
maxHP = maxHP+3
end
if input == "2" then
maxMP = maxMP+3
end
if input == "3" then
ATT = ATT+2
end
if input == "4" then
DEF = DEF+2
end
if input == "5" then
MAG = MAG+2
else
end
end
end

--HERE IS STATUS EFFECTS
function poison()
if STATUS == "POISONED" then
HP = HP-3
end
end

function regen()
if STATUS == "REGEN" then
HP = HP+1
end
end

-- END STATUS EFFECTS

function renderXP()
if XP >=1 and XP <= 10 then
paintutils.drawPixel(27,2, colors.green)
end
if XP >=11 and XP <= 20 then
paintutils.drawPixel(27,2, colors.green)
paintutils.drawPixel(28,2, colors.green)
end
if XP >=21 and XP <= 30 then
paintutils.drawPixel(27,2, colors.green)
paintutils.drawPixel(28,2, colors.green)
paintutils.drawPixel(29,2, colors.green)
end
if XP >=31 and XP <=40 then
paintutils.drawPixel(27,2, colors.green)
paintutils.drawPixel(28,2, colors.green)
paintutils.drawPixel(29,2, colors.green)
paintutils.drawPixel(30,2, colors.green)
end
if XP >=41 and XP <=50 then
paintutils.drawPixel(27,2, colors.green)
paintutils.drawPixel(28,2, colors.green)
paintutils.drawPixel(29,2, colors.green)
paintutils.drawPixel(30,2, colors.green)
paintutils.drawPixel(31,2, colors.green)
end
if XP >=51 and XP <=60 then
paintutils.drawBox(27,2,32,2, colors.green)
end
if XP >=61 and XP <=70 then
paintutils.drawBox(27,2,33,2, colors.green)
end
if XP >=71 and XP <=80 then
paintutils.drawBox(27,2,34,2, colors.green)
end
if XP >=81 and XP <=90 then
paintutils.drawBox(27,2,35,2, colors.green)
end
if XP >=91 and XP <=99 then
paintutils.drawBox(27,2,36,2, colors.green)
end
end

function healthBar()
hpP = HP/maxHP*100
if hpP == 100 then
paintutils.drawBox(6,2,10,2, colors.red)
end
if hpP >= 80 and hpP <= 99 then
paintutils.drawBox(6,2,9,2, colors.red)
end
if hpP >= 60 and hpP <= 79 then
paintutils.drawBox(6,2,8,2, colors.red)
end
if hpP >= 40 and hpP <= 59 then
paintutils.drawBox(6,2,7,2, colors.red)
end
if hpP >= 20 and hpP <= 39 then

paintutils.drawPixel(6,2, colors.red)
end
if hpP >= 0 then
end
end

function magicBar()
mpP = MP/maxMP*100
if mpP == 100 then
paintutils.drawBox(17,2,21,2, colors.blue)
end
if mpP >= 80 and mpP <= 99 then
paintutils.drawBox(17,2,20,2, colors.blue)
end
if mpP >= 60 and mpP <= 79 then
paintutils.drawBox(17,2,19,2, colors.blue)
end
if mpP >= 40 and mpP <= 59 then
paintutils.drawBox(17,2,18,2, colors.blue)
end
if mpP >= 20 and mpP <= 39 then
paintutils.drawBox(17,2,17,2, colors.blue)
end
if mpP >= 0 then
end
end

function saveGame()
fs.makeDir("/rpg/saves")
local file = fs.open("/rpg/".."save","w")
file.writeLine(HP)
file.writeLine(maxHP)
file.writeLine(MP)
file.writeLine(maxMP)
file.writeLine(ATT)
file.writeLine(DEF)
file.writeLine(MAG)
file.writeLine(XP)
file.writeLine(LV)
file.writeLine(STATUS)
file.close()
end

function loadGame()
file = fs.open("/rpg/".."save","r")
local fileData = {}
local line = file.readLine()
repeat
table.insert{fileData,line}
line = file.readLine()
until line == nil
file.close()
HP = fileData[1]
maxHP = fileData[2]
MP = fileData[3]
maxMP = fileData[4]
ATT = fileData[5]
DEF = fileData[6]
MAG = fileData[7]
STATUS = fileData[8]
LV = fileData[9]
XP = fileData[10]
print("Loaded save data!")
sleep(3)
end

-- HERE IS A TON OF VARIABLES
HP = 40
maxHP = 40
MP = 20
maxMP = 20
ATT = 1
DEF = 1
MAG = 1
STATUS = "OK"
LV = 0
XP = 99
-- HERE IS SOME ENEMY VARS
eHP = 5
eMP = 0
eATT = 1
eDEF = 0
eMAG = 0
eSTATUS = "OK"
eLV = 1
-- END OF VARIABLES
-- START BATTLE
loadGame()
drawHUD()
playerAction()
KingofGamesYami #2
Posted 20 July 2015 - 05:56 AM
if this file ("/rpg/".."save") doesn't have the data you want, it won't load properly and will probably end up setting all of your variables to 'nil'.

If you could post the contents of "/rpg/save", it would help.
Brod8362 #3
Posted 20 July 2015 - 06:19 AM
if this file ("/rpg/".."save") doesn't have the data you want, it won't load properly and will probably end up setting all of your variables to 'nil'.

If you could post the contents of "/rpg/save", it would help.

Am replying with mobile, can't give exact content of the file, but whenever the player activates the Save mechanism it saves the variables HP, maxHP, MP, maxMP, ATT, DEF, MAG, STATUS, XP, LV to the file "save". I have checked that file and it does save it, but I don't think it is loading it properly.
HPWebcamAble #4
Posted 20 July 2015 - 06:58 AM
Heres a quick function to take the lines of a file, and put them in a table:


local lines = {}

local f = fs.open("filepath","r")

for line in f.readLine do
  table.insert( lines , line )
end

f.close()

Also, I noticed this in your loadGame function:

table.insert{fileData,line}

I'm like 99% sure that should error, you need parentheses, not curly brackets.
'table.insert' is a function, so you call it like any other function.


Other than that, your loading function isn't great, but it should work (if you assign the variables the correct line for the 'fileData' table)
Edited on 20 July 2015 - 04:59 AM
Brod8362 #5
Posted 20 July 2015 - 05:16 PM
Heres a quick function to take the lines of a file, and put them in a table:


local lines = {}

local f = fs.open("filepath","r")

for line in f.readLine do
  table.insert( lines , line )
end

f.close()

Also, I noticed this in your loadGame function:

table.insert{fileData,line}

I'm like 99% sure that should error, you need parentheses, not curly brackets.
'table.insert' is a function, so you call it like any other function.


Other than that, your loading function isn't great, but it should work (if you assign the variables the correct line for the 'fileData' table)

I fixed the curly brackets, and then I had a different error occur. It seemed to have loaded the data, but now it putting some of the data in the wrong places. Its probably something I did wrong, so its fine.

I do have one more question - When it loads the data, instead of loading it as 56 its loads it as 56.0 . Can this be prevented?
Thanks.


EDIT - I did have an error in which it loaded the XP as the Status, which did cause an error but i fixed it. Now, I think its loading every value as a string instead of a number. Anyway to fix that?
Edited on 20 July 2015 - 03:19 PM
HPWebcamAble #6
Posted 20 July 2015 - 05:28 PM
I do have one more question - When it loads the data, instead of loading it as 56 its loads it as 56.0 . Can this be prevented?
Now, I think its loading every value as a string instead of a number. Anyway to fix that?

Easy, just use tonumber()


HP = tonumber( fileData[1] )
Note that if the fileData[1] string isn't just numbers, tonumber() will just return nil


tonumber( "1234" ) --#> 1234
tonumber( "1234hi" ) --#> nil

When its a number, it should display as '56.0', but I can't remember exactly why…
Brod8362 #7
Posted 20 July 2015 - 05:53 PM
I do have one more question - When it loads the data, instead of loading it as 56 its loads it as 56.0 . Can this be prevented?
Now, I think its loading every value as a string instead of a number. Anyway to fix that?

Easy, just use tonumber()


HP = tonumber( fileData[1] )
Note that if the fileData[1] string isn't just numbers, tonumber() will just return nil


tonumber( "1234" ) --#> 1234
tonumber( "1234hi" ) --#> nil

When its a number, it should display as '56.0', but I can't remember exactly why…

Using tonumber() worked! Also, it doesn't display the 56.0 when I used tonumber(). Thanks for the help!