I was trying to implement an armor item that enabled a bonus of +2 to "melee attack" using SetSkills with the LIB_BONUS feature.
When the item was equipped the bonus applied. However, when quickly equipping and unequipping the item the bonus started stacking. Initially melee attack was set at a value of 1 then after wearing the item melee attack was set to 3 as expected. If I removed and re-wore the item quickly the bonus started stacking - so 1 to 3, 3 to5, 5 to 7 , etc.
Interestingly, if I waited a few seconds after observing this stacking phenomenon then removed and rewore the item the skill and bonus went back to baseline. It seems that the mud needs some time to reset the bonus after unequipping the item. Here's the relevant code after SetWear( (:check_morality:) ) in the armor item file
varargs int check_morality(object who, string where){
int x, y, morality;
object env = environment(who);
morality = who->GetMorality();
x=who->GetSkillLevel("melee attack");
who->eventPrint("Melee attack before skill bonus = "+x+".");
//only less than 'good' chars can use
if( morality <=200 ){
object ob=new(LIB_BONUS);
ob->SetSkills( (["melee attack" : 2]) );
ob->eventMove(who);
x=who->GetSkillLevel("melee attack");
who->eventPrint("Melee attack after skill bonus = "+x+".");
who->eventPrint("You can feel an increase in your fighting "+
"prowess as you put on the gloves.");
if(env) tell_room(env, who->GetName()+" wears "+
GetShort()+".", ({who}));
return 1;
}
else {
who->eventPrint("You cannot seem to get your hands in "+
"the gloves.");
x=who->GetSkillLevel("melee attack");
who->eventPrint("Melee attack not wearing gloves = "+x+".");
return 0;
}
}
Here's the output I received - wearing and removing is in quick succesion:
(Morality is too high)
wear gloves
Melee attack before skill bonus = 1.
You cannot seem to get your hands in the gloves.
Melee attack not wearing gloves = 1.
(Reset morality)
call me->SetMorality(200)
OBJ(lash /secure/save/creators/l/lash) -> SetMorality( 200 ) = 200
wear gloves
Melee attack before skill bonus = 1.
Melee attack after skill bonus = 3.
You can feel an increase in your fighting prowess as you put on the gloves.
remove gloves
You remove a pair of swordsman gloves.
wear gloves
Melee attack before skill bonus = 3.
Melee attack after skill bonus = 5.
You can feel an increase in your fighting prowess as you put on the gloves.
remove gloves
You remove a pair of swordsman gloves.
wear gloves
Melee attack before skill bonus = 5.
Melee attack after skill bonus = 7.
You can feel an increase in your fighting prowess as you put on the gloves.
remove gloves
You remove a pair of swordsman gloves.
(After waiting about 5 seconds after removing the gloves)
wear gloves
Melee attack before skill bonus = 1.
Melee attack after skill bonus = 3.
You can feel an increase in your fighting prowess as you put on the gloves.
I was wondering if having a check for "if not worn" every heartbeat to do something like:
int check_gloves(string skill) {
write("Check gloves called");
if( !GetWorn() ) {
previous_object()->RemoveSkillBonus("melee attack", this_object());
return 0;
}
I had the above function called before checking for the morality condition but it did not make a difference in the stacking behaviour.