Here's a random obj stat changing routine I promised in my post. It changes the stats randomly for the object. Right now it's hard coded for one specific item but can easily be adapted to allow different items and different value limits. Call it from update_objects() with whatever frequency you want. something like "if(GET_VNUM(obj) == [obj you want randomized]) random_wpn(obj);" In the structure, location is the stat to change, max & min are the limits. Only one value is allowed to be negative at any time, and only one value can be max'ed. (This requires xapobjs at the moment.) The inital applies on the object are totally disregarded. Thanks to Gehn at velgarian for the idea. Author: mike@velgarian.sytes.net velgarian.sytes.net 4000 Use at your own risk. Drop me an email if you use it. Putting me in the credits is entirely up to you. void random_wpn(struct obj_data *obj) { #define VALS 4 static struct values { int location; int max; int min; } vals[] = { { 18, 5, -2}, // HR { 19, 5, -2}, // DR { 13, 15, -20}, // HP { 2, 4, -3} // Dex }; int winner = -1, loser = -1, location = -1; struct char_data *ch = NULL; bool max = FALSE; bool neg = FALSE; bool worn = FALSE; unsigned int rnd; int i, temp[VALS]; /* Pick 2 slots. Make sure they aren't the same. */ loser = winner = (random() % VALS); while(winner == loser) loser = (random() % VALS); for(i = 0; i < VALS; i++) { rnd = (unsigned int) time(NULL) + random(); srandom(rnd); temp[i] = (random() % (vals[i].max - vals[i].min + 1)) + vals[i].min; /* * 1: If negative and we already have a negative, do it again. * 2: If negative and don't have one, store it. * 3: If maxed and already have a max, do it again. * 4: If maxed and none are, store it. * * It's safe to decrement our counter within its own loop because there's no way we can * have both values true at the beginning of the loop. */ if((temp[i] < 0) && neg) { i--; continue; } if((temp[i] < 0) && !neg) { neg = 1; continue; } if((temp[i] == vals[i].max) && max) { i--; continue; } if((temp[i] == vals[i].max) && !max) { max = 1; continue; } } /* * If we didn't get a maxed or negative stat, set 'em from the winner/loser we generated before. * The random values of course take precedence over this though. */ if(!max) temp[winner] = vals[winner].max; if(!neg) temp[loser] = vals[loser].min; /* * Ok, we have all our random stats at this point. Now go change the applies. */ if(obj->worn_by) { worn = TRUE; location = obj->worn_on; ch = obj->worn_by; unequip_char(ch, location); } for(i = 0; i < VALS; i++) { obj->affected[i].location = vals[i].location; obj->affected[i].modifier = temp[i]; } if(worn) { equip_char(ch, obj, location); send_to_char(ch, "You feel a tingling sensation in your hand and feel slightly different.\r\n"); } }