@Will--
Potions with temporary bad effects are of very limited value. I usually only use !blind, !pois, !conf and the like exactly once per game--when I ID them. Very occasionally, I use them to ID runes. And that's it. Stat swap potions are more interesting.
Help me make my new variant! (please!)
Collapse
X
-
-
Off the top of my head I think it's player->stat_use[i] - player->stat_add[i] (because the first is the actual stat being used and the second is the bonuses), but that would bear some checking.Leave a comment:
-
Quick question for the potion of Mediocrity:
Is there a quick way to refer to the base stat rather than the current stat?
(As in base STR without any bonuses from equipment)Leave a comment:
-
-
Yes. There are several effects that do just that - do a search for effect_simple in effects.c for examples.Leave a comment:
-
Trying to figure out the effect handler code...
Can one effect handler call another effect handler?
For instance, I'm adding a potion of Mediocrity. So I have
bool effect_handler_MEDIOC(effect_handler_context_t *context)
in effects.c
with stuff like:
/* Stats (damage if over 16, raise if lower than 12) */
if (player->state.stat_ind[STAT_STR] > 16); <damage stat>
else if (player->state.stat_ind[STAT_STR] < 12); <raise stat>
Can the <damage stat> part of that use effect_handler_DRAIN_STAT() ?
Hmmm, it doesn't look like it because of the "context" stuff. I guess I'll just have to copy the relevant parts of DRAIN_STAT() into it 5 times...
(There's got to be a better way of doing this...)
EDIT: hmmm, I found this in the code for the LOSE_ALL monster attack:
effect_simple(EF_DRAIN_STAT, source_monster(context->mon->midx), "0", STAT_STR, 0, 0, 0, 0, &context->obvious);
Could I have one handler call another this way?Last edited by will_asher; April 29, 2021, 06:28.Leave a comment:
-
Oh yeah, and once you finish with this bit of character creation, *check it in*, for the reason above, and because smaller changes make code review by others much easier.Leave a comment:
-
Probably a good way to go about it, if you don't want to use memory validation.
But keep testing regularly so you don't get stuck this way again. This is a huge benefit of source control: only check in code that (mostly) works, and you will always have a reasonably stable place to test additional changes. "Mostly", because some bugs invariably sneak in anyway, or were present in the first place.Leave a comment:
-
Probably a good way to go about it, if you dont want to use memory validation.
But keep testing regularly so you don't get stuck this way again. This is a huge benefit of source control: only check in code that (mostly) works, and you will always have a reasonably stable place to test additional changes. "Mostly", because some bugs invariably sneak in anyway, or were present in the first place.Leave a comment:
-
Well, I didn't find the bug, but I reverted it back to before the largest commit, made some of the same changes (I'll save some of the crazier stuff I did for later), and it's working now.Leave a comment:
-
Git question: How do I revert the code back to how it was before the commit with the bug?
Do I have to re-clone the whole thing from github?
EDIT: I think I figured it out.Last edited by will_asher; April 28, 2021, 05:01.Leave a comment:
-
EDIT: ie could making a desc line too long in blow_methods.txt (or another of those txt files) cause a string to be too long?
I know monster.txt and artifact.txt obviously allow plenty of space for descriptions, but I don't know about the other txt files, and memory and string manipulating functions are parts of C where I don't understand much at all. (obviously)Leave a comment:
-
So a string that's in an array has a maximum length. How do I know how long it can be?
EDIT: ie could making a desc line too long in blow_methods.txt (or another of those txt files) cause a string to be too long?
I know monster.txt and artifact.txt obviously allow plenty of space for descriptions, but I don't know about the other txt files, and memory and string manipulating functions are parts of C where I don't understand much at all. (obviously)Last edited by will_asher; April 27, 2021, 04:45.Leave a comment:
-
If you’re talking about a constant string: “blah blah blah”, that can be long without any risk of memory problems.
If you’re putting strings into arrays (and that’s likely the final destination of strings in Angband), then your string plus the terminating null character cannot be longer than the array, or Bad Things happen. (Also, when working with unicode characters, things are even more complicated, because some characters are bigger than others; I know angband has left the world of straight ASCII, but I haven’t looked to see what’s being done.)
And many of the standard C string manipulation functions won’t stop you. They’ll just happily run off the end of the allocated memory for the array.
Now, it’s better than it used to be, in that there are standard library functions that are safer (strncpy instead of strcpy, for instance), and I’m pretty sure Angband has its own functions to ensure consistent usage, but it’s still easy to screw up.
Just as an example:
char *src = “blah blah blah”;
char *dest;
dest = malloc(strlen(src));
strcpy(dest, src);
Looks good, right? (Aside from the failure to check that malloc() actually returned valid memory, of course.)
but… strlen() returns the number of characters before the terminating null. strcpy() copies the terminating null.
So I just wrote a byte off the end of the array.
If I used the safer function, strncpy():
strncpy(dest, src, strlen(src));
Now it’s safe, until I try to do something else with the copied string. Since now the terminal null wasn’t copied, most of the string functions will keep reading off the end of the array, into whatever memory lies beyond.
These sorts of traps are why I suggested taking some time to learn C in a separate context.Leave a comment:
Leave a comment: