I want to change the scout and sniper skills into selectable realms. I want to make this change so that rangers can select the Nature Realm as primary and either scout or sniper skills as secondary. How would I do this?

Please keep in mind that I am very new to coding, but want to help out with PosChengband. If this works, I have other ideas for changes that I would like to code. Chris, if you are reading this, think of it as an investment in exchange for someone who can help you work on the project.

I want to change the scout and sniper skills into selectable realms. I want to make this change so that rangers can select the Nature Realm as primary and either scout or sniper skills as secondary. How would I do this?

Please keep in mind that I am very new to coding, but want to help out with PosChengband. If this works, I have other ideas for changes that I would like to code. Chris, if you are reading this, think of it as an investment in exchange for someone who can help you work on the project.

Thanks,

Riftor

The main problem is mixing book based spell casting with bookless techniques. You might want to take a look at how the Force-Trainer does this, though it requires some rather ugly hacks to work. For example, you might look at do_cmd_browse() in cmd5.c to get an idea of the spaghetti hacks that your proposal will require. The book based spell code is very old and very inflexible and really needs to be rewritten from scratch. But until that is done, then you will have no choice but to sprinkle more hacks throughout the old spell system to make things work.

As an aside, there is a partial refactor of the spell system in spells.c. This currently handles all the bookless casters but could certainly handle the book based casters as well (at some point in the future).

I can answer specific questions as you encounter them. An outline of how you might go about this request is:

[1] Remove the ability to choose a second realm in realm_choices2 in tables.c.

[2] Fix up the birth code. Sorry, but this is ugly and hard to do. You'll need to edit _prompt_realm2() in birth.c to prompt for "Sniper" or "Scout" powers. I'm not sure if you will be able to store this choice in player_type.realm2 or not. It would be nice if you could, but I don't trust the codebase to not get confused by this. You'll have to grep around and see if it will work. If it won't work, you'll have to add a new variable to player_type as well as corresponding load and save logic.

[3] Add hacks strategically in the old book based spell system. Search for how the Force-trainer does this (grep for INVEN_FORCE and select_the_force). Unless you want to attempt to complete the code refactor that I already started, but that project will probably take a lot of coding! (Perhaps you could just generalize the hack so it is only present once? The main problem is a UI problem. When the user presses 'm', their inventory is displayed so they can select a spellbook. Fine, but what about bookless guys? There is no inventory item and the code path here is deep, so hard to modify. You need a way for the user to say no, not a spellbook, use my technique instead, and the Force-Trainer does this by allowing the user to press 'w' I think).

[4] Share the existing Scout and Sniper spells. I see now that the Sniper is using powers rather than spells. You'll need to decide how you want this to play for the Ranger. Powers are accessed through the 'U' command and can be paid for with hp once mana runs out. They are not blocked by anti-magic. Spells are accessed through the 'm' command and can only be casted with mana.

[5] Consider non-spell aspects of your choice. For example, the Scout has flavorful bonuses and penalties depending on the current terrain they are fighting in. So you may need to modify the Ranger's calc_bonuses hook to share the Scout implementation.

I wasn't ignoring your original request. Rather, you are asking/comtemplating a difficult code change. And you know how lazy I tend to be

As an aside, I'll outline my ideas on the spell code refactor. This isn't how the code currently works, but how I plan to make it work some day in the future. With commentary!

[1] User (a new Ranger, say) presses 'm' to cast a spell.
[2] process_command in dungeon.c calls do_cmd_spell() in spells.c.
[3] do_cmd_spell() builds a spell table of legal, castable spells.
[3.1] This happens through a call to the class' get_spells hook.
[3.2] _get_spells() in class_ranger.c ends up being called. Change #1: Rather than using an inventory prompt, we build a menu of choices that includes the four Nature spellbooks if they are present in the inventory (pack_find_first(...)) as well as a choice for their technique realm. Easy peasy and no hacks required!
[3.3] User types 'e' (say) for the technique choice in this menu. _get_spells() then builds the spell table from the list of available techniques, consulting either the internal _sniper_spells[] table or the _scout_spells[] table.
[3.3'] Alternatively, (and this is Change#2) the user types 'b' for Nature Mastery. _get_spells() then builds the spell table from an internal table _nature_spells[1][]. No need for 8 spells per book, there can be any number. No need for the gargantuan and unmaintainable m_info.txt! Spell costs and fail rates are right next to the spell in question so you can instantly see them.
[4] Control returns to do_cmd_spell() in spells.c which now has a list of spells to present to the user. It doesn't know (or care) what realm they came from. Nor does it know (or care) that the ranger class had to prompt the user for a choice.
[5] User selects the spell to cast (spells are just function pointers) and do_cmd_spell() casts it.

This system would seamlessly handle book based casters, bookless casters, and classes that blend the two. It would unshackle the spell system from the dreaded gigantic switch system. It would allow arbitrary and even chageable/random spellbook contents. The only thing stopping me from this sort of change is the huge amount of legacy code ...

Wow. Thanks for all the information. Let me work on the quick hack first so that I can build some knowledge. I will help you out when you are ready to start the overhaul.

I know that you weren't ignoring my original request. Real life has the annoying habit of getting in the way. I've also learned that, with Angband, it's better when help comes hand in hand with suggestions. Your reply is actually the most receptive response I've had to one of my ideas. I appreciate it and look forward to working together.