/* Quest Bits for Mobprogs by Igor van den Hoven. The Diku and Merc license apply. This code is compatible with smaug muds. */ /* The idea of this snippet is to move away from the traditional if value == (number between -2 and +2 billion) check. Given the average quest has around 10 steps you only need 4 bits of a 32 bit integer to store it. If you have a large area and a quest value assigned for a player for that area you can add a total of eight 10 step quests stored in a 32 bit integer. Using quest[MAX_VNUM / 100] is an easy way to create a quest value for each area, and you can access it with: ch->pcdata->quest[mob->vnum / 100] with ch being the player and mob being the mob setting the quest value. In this code you define a bit range by giving the first bit, next giving the number of bits, followed by the value you want those bits to hold. 4 bits would give a value between 0 and 15, 8 bits a value between 0 and 255 (which should be enough for everyone). To set a quest value you'd use: mpmset $n quest 0 4 1. 0 would be the first bit, 4 would be the total number of bits, and 1 is the value to assign to them. To check if bit 1 to 4 has the value 1 you'd use: if quest (0,4,$n) == 1. When adding another quest you'd start out with: if quest (4,4,$n) == 0 to see if the player has or hasn't started the quest assigned to bit 5 to 8. Methods for saving and reading aren't included, this is pretty much a proof of concept. */ // In mud_prog.c add these two functions: int get_quest_value(int quest, int fBit, int nBit) { int cnt, value = 0; for (cnt = fBit ; cnt < fBit + nBit ; cnt++) { if (IS_SET(quest, 1 << cnt)) { SET_BIT(value, 1 << (cnt - fBit)); } } return value; } void set_quest_value(int *quest, int fBit, int nBit, int value) { int cnt; for (cnt = fBit ; cnt < fBit + nBit ; cnt++) { if (IS_SET(value, 1 << (cnt - fBit))) { SET_BIT(*quest, 1 << cnt); } else { REMOVE_BIT(*quest, 1 << cnt); } } } // In mprog_do_ifcheck add: if( !str_cmp( chck, "quest" ) ) { int fBit, nBit; char name[MAX_INPUT_LENGTH]; if (sscanf(arg, "%d,%d,%s", &fBit, &nBit, name) != 3) { return 0; /* error */ } if ( name[0] == '$' ) { switch ( name[1] ) { case 'i': chkchar = mob; break; case 'n': chkchar = actor; break; case 't': chkchar = ( CHAR_DATA * ) vo; break; case 'r': chkchar = rndm; break; default: return 0; /* error */ } } if (chkchar) { if (IS_NPC(chkchar) { lhsvl = get_quest_value(chkchar->quest, fBit, nBit); } else { lhsvl = get_quest_value(chkchar->quest[mob->in_room->area->low_r_vnum / 100], fBit, nBit); } rhsvl = atoi(rval); return mprog_veval(lhsvl, opr, rhsvl); } else { return 0; /* error */ } } // In mpxset.c add: if( !str_cmp( arg2, "quest" ) ) { int fBit, nBit, value; if (sscanf(arg3,"%d %d %d", &fBit, &nBit, &value) != 3) { return; } if (IS_NPC(victim) { set_quest_value(&victim->quest, fBit, nBit, value); } else { set_quest_value(&victim->quest[ch->in_room->area->low_r_vnum / 100], fBit, nBit, value); } return; } // In mud.h add to char_data: int quest; // And to player_data; int quest[MAX_VNUM/100];