Skip to content

Conversation

@Allofich
Copy link
Collaborator

@Allofich Allofich commented Nov 4, 2025

This covers lots of things but they are all related to item generation.

First, there are some corrections to existing things:

  1. For loot generation, I had made the code get the number of items in a loot object before generating them. What the original game actually does is roll for each of four slots (gold, magic item, non-magic weapon/armor, magic weapon/armor), and set a value to 1 or 0 for each of these four slots depending on if the roll succeeded. Then, for each slot that is 1, it generates an item. This PR recreates this behavior.
  2. The weapon generation (which wasn't hooked up to anything yet) was picking a random ID, then if that didn't satisfy the quality requirement it would iterate forward through the rest of the weapon list until it found one that did. What the original game actually does is keep picking random IDs from the range of possible IDs until one that meets the quality requirement is met. This PR recreates this behavior.
  3. The ItemLibrary used armorNames ("Cuirass", etc.) to get the names for plate armor items and had plateArmorNames commented out with a comment that you weren't sure "ordinary" plate exists in the game. The original game uses plateArmorNames ("Plate Cuirass", etc.) for plate armor without a material bonus. This PR gets the names from plateArmorNames now and has commented out armorNames until materials are handled.

Next, the new things:

  1. Gets non-magic weapons and armors for loot objects like the original game.

  2. During this process the original game calls a function to get the item quality, but it doesn't use the result, overriding it with 16. The function is also called during magic item generation, which isn't implemented yet. The function is included in this PR for later use with magic item generation.

  3. In the process of getting the non-magic weapon or armor, the original game refers to a set of values that looks like [0, 0, 1, 1, 0], which is accessed using the lootValueIndex. A 0 means to generate with either 25% condition, 75% condition or 100%, like with items on creatures, while a 1 means to generate with either 75%, 100% or 100% (2/3 chance of 100%). Effectively this means that these weapons and armor found in places with index 2 or 3 (NOBLE or DUNGEON) are more likely to have good condition. Since item condition isn't handled yet this isn't hooked up, but the code is there.

  4. Added some simple functions to use the itemIDs returned by the Arena functions to get items from the OpenTESArena ItemLibrary via the item display names. Feel free to replace these if you want. While making them I discovered that there is a discrepancy in shield names. The armor lists for leather, chain and plate use "Kite shield" and "Tower shield" with a lowercase "s," and this (specifically, the plate list) is what the original game uses for getting the names of these items when generating a non-magic armor/weapon (BTW, the non-magic armor/weapon generation also means no material bonus). Meanwhile the armorValues list, which is used to create names of material plate armor, uses "Kite Shield" and "Tower Shield". ItemLibrary is getting the names for shields from this list, so in the itemID-to-name function, I replace "shield" with "Shield," since I am reading the names from plateArmors, to match the names in ItemLibrary. I used these functions to hook up non-magic weapon and armor generation to item generation on creatures and in loot. Only plate armor will appear (as explained in Recreate Arena logic for weapon/armor generation #301). Any leather or chain items that appear are due to the test placeholder for magic weapons and armor, not these functions. The non-magic weapons/armor that appear on creatures are not 1-to-1 with the original game because they aren't affected by the can-equip check.

@afritz1
Copy link
Owner

afritz1 commented Nov 4, 2025

Thanks, looking this over. I don't love the string comparisons and Shield/shield stuff because that will break with translated mods. Need to think.

@Allofich
Copy link
Collaborator Author

Allofich commented Nov 4, 2025

Regarding Shield/shield, although it looks nicer to have "Kite Shield" and "Tower Shield" because the capitalization is consistent with other items (including "Round Shield"), the original game uses the names from plateArmors for all the no-material, non-magical shields, which gives "Kite shield" and "Tower shield." If you use those in ItemLibrary you could remove the "shield" -> "Shield" conversion. Or, you could get the names of the kite shield and tower shield from armorNames, the same way ItemLibrary does. That would also remove the need for the string replacement.

If by translated mods you mean translations of the original game executable, wouldn't those then work because all the names are read from the executable?

@afritz1
Copy link
Owner

afritz1 commented Nov 4, 2025

Ohhh it's because the two name arrays have inconsistent casing, lame. You tried mapping the original items to ItemLibrary items by name. This should probably do an itemID lookup instead.

@afritz1
Copy link
Owner

afritz1 commented Nov 4, 2025

I think my fix should work for loot piles, they'll always be plate.

@Allofich
Copy link
Collaborator Author

Allofich commented Nov 4, 2025

I think my fix should work for loot piles, they'll always be plate.

Yes, but I see that as a mistake in the original game's code, currently replicated by the helper (I think it's supposed to randomly be leather, chain or plate). I was thinking eventually we would have an option to fix, such as by having multiple helper functions (fixed ones, original buggy ones, etc.). I don't think it should be hardcoded outside of the helper functions.

The "always being plate" occurs for both loot piles and items on creatures, as they both call the same function, using -1 for material. I'm not sure about human enemies yet, although I believe they can have leather or chain by specifying the material instead of using -1.

Also, you may have noticed but I don't think the new lookup functions are handling shields yet.

Also allows any armor material, not just plate.
@Allofich
Copy link
Collaborator Author

Allofich commented Nov 4, 2025

I see you changed it to random material, and fixed for shields. The random material patches the result of the helper function to what I theorize as the intended behavior, but shouldn't we just add an out parameter for base material to getCreatureNonMagicWeaponOrArmor and getLootNonMagicWeaponOrArmor (and continue to use their results)? The only reason I hadn't done that yet was because we weren't actually using the material in looking up from the ItemLibrary yet.

@afritz1
Copy link
Owner

afritz1 commented Nov 4, 2025

Okay, it's hardcoded to Plate in those ArenaEntityUtils functions.

@Allofich
Copy link
Collaborator Author

Allofich commented Nov 4, 2025

I think that's fine for now. Enemy humans can have leather or chain, but they will be using a new function to initiate armor generation. For them, we'll need to retrieve the base material from pickNonMagicArmor, possibly by adding an out parameter. We could then also use that out parameter for getCreatureNonMagicWeaponOrArmor and getLootNonMagicWeaponOrArmor (pickNonMagicArmor having interpreted -1 as plate), instead of hardcoding it at their returns. But I don't think it matters now, I can do that in a future PR, and you can evaluate it then.

@afritz1 afritz1 merged commit ec007b0 into afritz1:main Nov 4, 2025
3 checks passed
@Allofich Allofich deleted the loot branch November 4, 2025 19:46
@afritz1
Copy link
Owner

afritz1 commented Nov 4, 2025

Will be glad once we're done with this ancient hacky game logic.

@Allofich
Copy link
Collaborator Author

Allofich commented Nov 4, 2025

I'm mostly just doing this as a hobby, as I get satisfaction out of the mental exercise and seeing the game slowly come to life. But I'd say don't feel like you have to quickly respond to my PRs or even keep the project going if you get tired of it. Who knows, in a few years we might be able to just ask an AI to finish the whole thing for us.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants