19 Dec, 2012, triskaledia wrote in the 1st comment:
Votes: 0
I wanted to add a check for secondary weapons to have a chance to level up if they are relics.
Original thought was to test to see if one weapon or the other weapon was present; no particular reason.
Then after I got the code to quit crashing (see commented part), I thought, what if the main weapon
gets disarmed during combat, I still want the second one to gain exp. I thought I added enough checks for
the secondary weapon not being NULL, but either I've overlooked a spot, or I just can't do what I want.
Any thoughts?
wield = get_eq_char( ch, WEAR_WIELD );  wield2 = get_eq_char(ch, WEAR_SECONDARY);
if (wield != NULL && wield2 != NULL) //if I change && to || it crashes the mud.
{
livingweap_needed = (wield->weapon_level * 750);
lwn2 = wield2->weapon_level * 750;

if (IS_OBJ_STAT (wield, ITEM_RELIC) || IS_OBJ_STAT(wield2, ITEM_RELIC))
{
if (wield->weapon_level >= 100) return; if (wield2->weapon_level >= 100) return;
livingweap_exp = (xp / 10);
xp -= (livingweap_exp);

sprintf(buf, "{B- {gYour %s {greceives {w%d {gexperience points.{x\n\r", wield->short_descr, livingweap_exp);
stc(buf, gch);
if(wield2 != NULL)
{sprintf(buf, "{B {gYour %s {greceives {w%d {gexperience points.{x\n\r", wield2->short_descr, livingweap_exp);
stc(buf, gch);}


wield->weapon_currentxp += livingweap_exp; if(wield2 != NULL) wield2->weapon_currentxp += livingweap_exp;
if (wield->weapon_currentxp >= livingweap_needed )
{
wield->weapon_level++;
wield->value[1] += number_range(0, 1);
wield->value[2] += number_range(0, 3);

sprintf(buf, "%s has gained a level.{x\n\r", wield->short_descr);
stc(buf, gch);
wield->weapon_currentxp -= livingweap_needed;
wield->weapon_points++;
}
if (wield2->weapon_currentxp >= lwn2 && wield2 != NULL)
{
wield2->weapon_level++;
wield2->value[1] += number_range(0, 1);
wield2->value[2] += number_range(0, 3);

sprintf(buf, "%s has gained a level.{x\n\r", wield2->short_descr);
stc(buf, gch);
wield2->weapon_currentxp -= lwn2;
wield2->weapon_points++;
}

}
}
19 Dec, 2012, Rarva.Riendf wrote in the 2nd comment:
Votes: 0
Yep, instead of duplicating code (a very bad coding practice) , make a function that check weapon individually.

checkItem(ch, WEAR_WIELD, xp );
checkItem(ch, WEAR_SECONDARY, xp );

void checkItem(CHAR_DATA *ch, int slot, int xp) {
OBJ_DATA *obj = get_eq_char(ch, slot);
if (!obj || !IS_OBJ_STAT (obj, ITEM_RELIC))
return;

//insert whatever you want to do with your object here
}


You can see that this way, you are not even limited to weapon.
19 Dec, 2012, triskaledia wrote in the 3rd comment:
Votes: 0
Exactly what I ended up doing, thanks Rarva. Works a lot better and can check both weapons without crash.
19 Dec, 2012, mangan wrote in the 4th comment:
Votes: 0
Glad to hear that Rarva's change assisted you. To promote learning, realize the logic that the OR states. It means either 'wield' OR 'wield2' must not be NULL in order to enter the code block. Conversely, this means that either 'wield' OR 'wield2' can be NULL, as long as the other isn't, and you still enter the code block.

wield = get_eq_char( ch, WEAR_WIELD );  wield2 = get_eq_char(ch, WEAR_SECONDARY);
if (wield != NULL && wield2 != NULL) //if I change && to || it crashes the mud.
{
livingweap_needed = (wield->weapon_level * 750);
lwn2 = wield2->weapon_level * 750;


In your prior version of the code (as you quoted it before Rarva's suggestion), imagine that either 'wield' or 'wield2' is NULL, and the other is not. (Choose which one arbitrarily.) The first two lines inside the code block dereference the 'wield' and 'wield2' pointers (via the arrow operations) when getting the weapon level, which will cause a crash if either of them are NULL.

The switch as Rarva suggested separates the logic between the two weapons. This does a NULL check for the given item and proceeds if it is valid (not NULL), independent of other items.

Hth in future issues.
19 Dec, 2012, Igabod wrote in the 5th comment:
Votes: 0
thanks for the explanation mangan. Though I already knew this information I am certain it will be helpful for those who are just starting out. I hope to see you post more helpful information like this in the future.
0.0/5