(bit of rambling background context in this in case it helps, I've included a tl;dr underneath if you just want the barebones question)
Hi all, for the past few days I've been working on a single user tool used to generate custom content for people in the Digimon community to mod their "Digital Monster Ver. Color" virtual pet toy.
Without this tool, the only way to do it is to manually go in and edit the hex data, and even using something like imHex with a good pattern file, it's very easy to get lost and confused - so this program gives a GUI for the user to manually edit the stats (and eventually evolution paths) for their custom Roster, which it adds to a list, converts it to hex, and exports it as a text document, which they can then just paste into their hex editor at the right memory address.
Here's a screenshot:
https://i.imgur.com/16Y2sJR.png
I know BYOND is not the ideal platform for this sort of program, but I am not much of a programmer (my full-time job is actually pixel art).
I've dabbled in Byond on and off since 2001 and for whatever reason, DM is the only programming language that I've ever been able to muddle my way around, but even then I would treat my knowledge somewhere between "complete beginner" and "able to combine tutorials and examples to get something functional."
I need a (preferably easy to understand) way to save user-uploaded icons which have been modified in code. The system I made accepts any of the commonly used formats for Digimon sprite sheets (eg it'll take a 3x4 grid of 16x16 sprites, a 1x15 line of 48x48 sprites, etc.)
It then chops the sprite into two frames, so the Digimon has a little bit of animation while it's on the screen. These frames are saved as obj/Roster/var/firstFrame and obj/Roster/var/secondFrame as /icon.
My gut says maybe something using ftp to save them, using a format like '[DigimonName]_Frame1.png' and '[DigimonName]_Frame2.png' would work, but I can't quite get my head around how to load them in again, given the names will vary depending on whatever the player has named each Digimon in their Roster.
I also thought about assigning each roster "slot" its own ID, and saving/loading the filenames like that, but because the roster size can vary from literally 1 to 90 (though my program only supports around 64 currently) it feels a bit wasteful to cycle through each slot and keep track of whether a slot is active or not in order to save its icons, but I guess that could maybe be a bit of a clunky workaround.
I've read some of the forum posts and the reference for ftp and I feel like the main issue could just be that my lack-of-programmer-brain is maybe just not quite understanding how it works, but I'm keen to learn more!
Problem description tl;dr version:
I need a way to save user-uploaded icons which have been modified in code which is compatible with dmm_suite. The player can currently save their work, load their work, and have everything loads fine, apart from the icons they've set up.
Asking the user to set up their icons multiple times will be quite a large point of frustration for them (these rosters can get pretty sizeable, with commonly over 60 icons which would need re-applied each time.)
Any help would be appreciated! Thanks in advance!
Here's my code for the icon generation and saving/loading sections. I don't mind uploading the whole project source if it helps resolve my issue too - I'm not too precious about it!
Code:
obj/Roster/
DblClick()
..()
if(writing) return
var/I = input("Select an icon for this [name] level Digimon.",icon) as null|icon
if(I==null)
return
customicon=1
edited=1
var/icon/picture=icon(I)
var/icon/picture2=icon(I)
var/IW = picture.Width()
var/IH = picture.Height()
var/IW2 = picture2.Width()
var/IH2 = picture2.Height()
if(IH == 720)
picture.Scale(16,240)
picture2.Scale(16,240)
IW = picture.Width()
IH = picture.Height()
IW2 = picture2.Width()
IH2 = picture2.Height()
picture.Crop(1,IH, 16,IH-15)
picture2.Crop(1,IH2-16, 16,IH2-31)
IW = picture.Width()
IH = picture.Height()
IW2 = picture2.Width()
IH2 = picture2.Height()
else if (IH==64)
picture.Crop(1,IH, 16,IH-15)
picture2.Crop(17,IH,32,IH-15)
IW = picture.Width()
IH = picture.Height()
IW2 = picture2.Width()
IH2 = picture2.Height()
else if(IH==16)
picture.Crop(1,16, 16,1)
picture2.Crop(1,16,16,1)
IW = picture.Width()
IH = picture.Height()
IW2 = picture2.Width()
IH2 = picture2.Height()
else if(IH==48)
picture.Crop(1,48, 48,1)
picture2.Crop(1,48,48,1)
IW = picture.Width()
IH = picture.Height()
IW2 = picture2.Width()
IH2 = picture2.Height()
else
alert(usr,"Please use a DMColor long sprite sheet, a Tortoiseshel grid sprite sheet, or an individual 16x16 or 48x48 sprite in .png format.","Error"," Okay sorry :( ")
return
picture.Scale(32,32)
picture2.Scale(32,32)
picture.SwapColor(rgb(0,255,0,255),rgb(0,255,0,0))
picture2.SwapColor(rgb(0,255,0,255),rgb(0,255,0,0))
firstFrame=picture
secondFrame=picture2
src.icon=picture
src.name=input("Enter Digimon name!",name) as text
mob/proc/SaveFile()
var /dmm_suite/suite = new()
var mapText = suite.write_map(
locate(1, 1, 1),
locate(world.maxx, world.maxy, world.maxz),
DMM_IGNORE_PLAYERS
)
src << "<pre>[mapText]</pre>"
var/datetime=time2text(world.realtime, "-hh-mm_DD-MM-YYYY")
src << text2file (mapText, "Roster[datetime].dmm")
alert(usr,"Saved a .dmm backup of your Roster as \"Roster[datetime].dmm\" in the DMColor folder.","Roster Saved","Okay!")
mob/proc/LoadFile()
var/dmm_file=input("Pick a .dmm Roster file to load.","File") as null|file
if(!null)
var file_name = "[dmm_file]"
var file_extension = copytext(file_name,length(file_name)-2,0)
if(file_extension != "dmm")
usr << "Supplied file must be a .dmm file."
return
for(var/obj/O in world)
del(O)
sleep()
var /dmm_suite/suite = new()
var map_text = file2text(dmm_file)
suite.read_map(map_text, 1, 1, 1)
I guess I'm not really understanding your question. Is it something about the filenames that presents the issue?