lushen124 / Universal-FE-Randomizer

Properly universal this time.
MIT License
98 stars 28 forks source link

Added support for battle palettes when shuffling characters. #412

Closed lushen124 closed 8 months ago

lushen124 commented 1 year ago

I updated the code to support the ability to override a palette as long as it has at least a set of hair colors and a set of primary colors, with optional sets of secondary and tertiary colors. Currently, character shuffling does not update the battle palettes, so characters that get shuffled in use the palette of the character they replace. With this change, the JSON file can now set up override palettes that will be applied as necessary when these characters are shuffled in.

Using FE6 Roy as an example, here is the JSON blob now:

{
    "name": "Roy",
    "portraitPath": "portraits/FE6/roy.png",
    "paletteString": "344FFF6B7F479E2ED91D6E2D0B319F005B0CF324707F2B7E6969494DFF1FFF7F",
    "description1": "The next heir to Pherae.",
    "description2": "The protagonist of this story.",
    "battlePalette": {
        "hair": ["#f82000", "#d81018", "#983848"],
        "primary": ["#5888f8", "#4858d0", "#485098"],
        "secondary": ["#f8f838", "#f0a058", "#c87038"],
        "tertiary": null
    },
    "characterClass": "LORD",
    "level": 1,
    "bases": {
      "hp": 0,
      "str": 2,
      "skl": 2,
      "spd": 3,
      "def": 0,
      "res": 0,
      "lck": 7
    },
    "growths": {
      "hp": 80,
      "str": 40,
      "skl": 50,
      "spd": 40,
      "def": 25,
      "res": 30,
      "lck": 60
    },
    "weaponRanks": [
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0
    ],
    "constitution": 0,
    "originGame": "FE6",
    "eyeX": 3,
    "eyeY": 4,
    "mouthX": 2,
    "mouthY": 6
  }

And this is the effect:

FE8 Rando 2-0

I'll be in the process of pulling color sets from the portraits to apply them to the JSON.

Thanks to @Geeene for the work on implementing the shuffling feature to begin with!

Geeene commented 1 year ago

Ah that is very nice thanks :)

I had used this file here to generate the JSONs initially:

https://github.com/Geeene/Universal-FE-Randomizer/blob/387e3ddcfc2b79262efc9c6e8730c71600cdd9d2/Universal%20FE%20Randomizer/src/application/MainShort.java

(the main functions with GENERATOR in the name)

From what little I currently understand of the Pallette logic, it should be possible to reuse this and take the information from these enums right?

fedata.gba.fe6.FE6Data.Palette fedata.gba.fe6.FE7Data.Palette fedata.gba.fe6.FE8Data.Palette

lushen124 commented 1 year ago

Oh, I didn't realize the JSON files were programmatically generated 🤣

But yeah, in theory, you could rip it directly from their base games since the palette should be the same format and should drop right in without too much of a fuss, but I think you do get cleaner results if you can more directly specify the color sets. Ultimately, that's what the palette logic is doing. It's just extracting what it considers "hair", "primary", "secondary", and "tertiary" colors where possible from what it knows about the battle palettes of the character's normal classes. As such, some characters need workarounds because their class may not provide, for example, a hair color, because the battle animation has them wearing a helmet. You can see the workaround in the supplementary hair colors each game provides for some characters (FE6 for example: https://github.com/lushen124/Universal-FE-Randomizer/blob/master/Universal%20FE%20Randomizer/src/fedata/gba/fe6/FE6Data.java#L1983) This is especially true when the user also wants to randomize classes.

The other benefit of this approach is it can support custom characters that weren't in any of the base games, like your Ilyana example. In fact, that's an idea I've been playing around with: allowing users to specify their own cast. Your button to load custom configurations gave me an idea to allow users to put in whatever characters they deem fit, as long as it contains the relevant JSON and portrait data (and who knows, in the future, battle animations). I haven't thought too much about the technical details yet, but it definitely seems possible. All we'd need is some way to package up a manifest file with the png, like a custom zip extension that we can then extract and process on the fly.

Geeene commented 1 year ago

Yeah I had removed that MainShort class from the branch at some point (which was probably a mistake) because I wasn't sure if it'd be good to have competing main methods in the jar etc, but these files would certainly be a massive pain to generate manually lol.

I definetly agree with having the information in the json files, just generate them from the Information in the Enums, then have Gson serialize it to Json. (Unless I'm misunderstanding the issue with this)

I certainly agree with building your own cast being a really cool possiblity, it's a big reason of why I implemented it through Jsons rather than f.e. just having hardcoded enums, as it is much more feasible for an end user to add their own characters

lushen124 commented 1 year ago

Yeah, I'm not arguing against having it in the JSON, I'm just saying we don't need to re-generate the JSON and pull in the palette from the other games directly because we get better/controlled results if we just set it manually in the JSON. The downside, of course, is that it's a manual process, but it's not hard. It's just taking an eyedropper tool to all of the portraits and grabbing 6 - 12 colors from it.

Geeene commented 1 year ago

I see, makes sense

lushen124 commented 1 year ago

I also realized that, when testing this, that the JSON files include personal bases only, without class bases. We should include their effective bases (that is, personal + class bases) because the target game may not have the class data for the character. I had a Duessel shuffled into FE6 who ended up starting with more or less straight 0s because Great Knights don't exist in FE6, so it assumes 0 for class bases, and then de-levels him further. I will be updating all of the bases to their combined values.