This isn't too shabby
An if statement is followed by an expression in parenthesis, and then the code to run if the expression evaluates to true (or !=0 in C). This code can be either a single line (so it just follows the expression) or a block of code (so it is wrapped in a new scope with {}'s).
So a little info about the expression. The expression uses
boolean logic
to determine if the total is true or false. This means that A && B is true if both A and B is true. It means that A || B is true if either A or B is true. It means that A && (B || C) is true if A is true and one or more of B and C is true. It matters how the parenthesis is are place. (A &&
|| C - the same statement as before, but with different placing of the parenthesis - is true if A and B are true, or C is.
Because boolean logic is hard (at least, it's usually where I find
my bugs), it pays off to try and simplify those expressions. The same logic can typically be represented by a series of if statements:
Code:
void perform_raceelf()
{
struct char_data *ch;
for (ch = character_list; ch; ch = ch->next) {
if (GET_RACE(ch) != RACE_ELF) // note - this is the opposite check of what you used.
continue; // We're filtering out instead of including. this statement means, done with this char, see next.
if (GET_POS(ch) == POS_FIGHTING || GET_POS(ch) == POS_MORTALLYW || GET_POS(ch) == POS_INCAP)
continue;
if (GET_HIT(ch) >= GET_MAX_HIT(ch))
continue;
// all who pass the above checks are elves with less than max hitpoints who are not fighting or dying.
GET_HIT(ch) += 4 + GET_LEVEL(ch) /5;
if (GET_HIT(ch) > GET_MAX_HIT(ch))
GET_HIT(ch) = GET_MAX_HIT(ch);
send_to_char(ch, "Your wounds heal on their own.\r\n");
act("$n's wounds heal on their own.", TRUE, ch, 0, 0, TO_ROOM);
}
}
A side effect of structuring your loops this way is that it is easy to add another check (ie. level, class, etc.) because each section of the code does one particular thing.