Opened 12 years ago

Closed 10 years ago

#803 closed task (fixed (in master))

Create elem_table (slay_table for elements)

Reported by: magnate Owned by: magnate
Milestone: 3.3.0 Keywords: cleanup


Working on [da7e0c7] (SVN r1220) has made me think about Angband's long tradition of portability and tweakability (for variants, or just personal preference).

First, I need to tidy up the clumsy code in eval_r_power (init1.c) and make it easier to read and understand. But I aspire to reduce it dramatically by creating some abstracted macros which can be used in loops:

similar object flags: brands/slays/resists

breath damage

monster ball/bolt spell damage

There's no reason long lists of these should appear in more than one place: currently brands and slays are gathered in longhand in all of randart.c, obj-desc.c and attack.c, and resists in many places. The breath and monster spell attacks have been abstracted to monster/constants.h, but they're still called in long lists rather than in loops.

There are other constants which could be abstracted too, like player spell effects, potion and scroll numbers (amounts, durations), even things like the effects of disturbance. I don't know so much about these so will tread carefully.

My aspiration in increasing abstraction is two-fold: one is to make the code easier to maintain, and the other is to make it easier for people to change things if they want. So if all this stuff is in constants.h, you can add time resistance or smegma breath to the game with a minimum of other files to edit.

I'll post periodic progress (or problem) reports - other comments welcome.

Change History (9)

comment:1 Changed 12 years ago by takkaria

Watch out that you strike a balance between "easier to maintain" and just abstracting things out because they can be. For example, factoring out activation and item use effect durations in effects.c won't get you anywhere, since they're only used in one place.

comment:2 Changed 12 years ago by magnate

  • Owner set to magnate
  • Status changed from new to assigned

comment:3 Changed 12 years ago by magnate

Well, the introduction of slay_table seems to have worked ok and saved us quite a few lines of code, without adversely affecting readability. My next plan is a more ambitious version of a similar idea: res_table of type elem_t, whose structure is:

const char *element /* the element name */
u32b player_res_flag /* the flag for RES_FOO */
u32b player_tmd_flag /* the flag for TMD_FOO */
u32b player_imm_flag /* the flag for IMM_FOO */
u32b player_vuln_flag /* the flag for VULN_FOO */
u32b monster_res_flag /* the monster flag for IM_FOO */
u16b breath_cap /* the maximum breath damage */
u16b breath_divisor /* the monster hp divisor for breath damage */
u16b res_numerator
u16b res_divisor /* fixed part of the resistance denominator */
u16b res_rand /* variable part of the resistance divisor */
u16b ball_dmg /* fixed part of ball damage */
s16b ball_rlev /* rlev-dependent part of ball damage */
s16b ball_rand /* random part of ball damage */
u16b bolt_dmg
s16b bolt_rlev
s16b bolt_rand /* as above for bolt damage */

It should be possible to reconstruct almost all the existing BO_FOO and BA_FOO damage formulae from the above, by using negative values for 1/x. e.g. if ball_rlev is -3, then the rlev part of the damage is rlev/3 ... will do some more work to see if anything isn't coverable before committing anything. I'm hopeful that this will generate significant improvements in the code, because there are a large number of places where we loop over every single element...

comment:4 Changed 11 years ago by magnate

  • Keywords cleanup added

comment:5 Changed 11 years ago by magnate

This would enable checking for resistance holes for, e.g. #992.

comment:6 Changed 11 years ago by magnate

  • Milestone changed from Future to 3.2.0
  • Summary changed from Thoughts on abstraction to Create elem_table (slay_table for elements)

Probably need to move slay_table out of obj-info.c while we're at it - these both belong in header files somewhere. src/monster/types.h is my guess.

comment:7 Changed 10 years ago by magnate

  • Milestone changed from 4.0 to 3.3.0

comment:8 Changed 10 years ago by magnate

  • Status changed from assigned to pending

Ok, this is finally in staging [rebdff52]. It's called gf_table and it's in src/spells1.c where all the projection stuff happens. It took so long because I hadn't twigged the conceptual distinction between a GF_ type and a monster spell. There's now a separate mon_spell_table in src/monster/mon-spell.c, and a third table for side effects is also in there (though that could move to spells1.c). Thanks to takkaria for helping clarify my thinking.

comment:9 Changed 10 years ago by magnate

  • Resolution set to fixed
  • Status changed from pending to closed

In master as of [r7dda40c].

Note: See TracTickets for help on using tickets.