In oasis.h we have our defines
Code:
#define MAX_OBJ_REPOP 100
#define OEDIT_REPOP 29
In oasis.c we edit our menu.
Code:
/* Display main menu. */
static void oedit_disp_menu(struct descriptor_data *d)
{
char buf1[MAX_STRING_LENGTH];
char buf2[MAX_STRING_LENGTH];
struct obj_data *obj;
obj = OLC_OBJ(d);
get_char_colors(d->character);
clear_screen(d);
/* Build buffers for first part of menu. */
sprinttype(GET_OBJ_TYPE(obj), item_types, buf1, sizeof(buf1));
sprintbitarray(GET_OBJ_EXTRA(obj), extra_bits, EF_ARRAY_MAX, buf2);
/* Build first half of menu. */
write_to_output(d,
"-- Item number : [%s%d%s]\r\n"
"%s1%s) Keywords : %s%s\r\n"
"%s2%s) S-Desc : %s%s\r\n"
"%s3%s) L-Desc :-\r\n%s%s\r\n"
"%s4%s) A-Desc :-\r\n%s%s"
"%s5%s) Type : %s%s\r\n"
"%s6%s) Extra flags : %s%s\r\n",
cyn, OLC_NUM(d), nrm,
grn, nrm, yel, (obj->name && *obj->name) ? obj->name : "undefined",
grn, nrm, yel, (obj->short_description && *obj->short_description) ? obj->short_description : "undefined",
grn, nrm, yel, (obj->description && *obj->description) ? obj->description : "undefined",
grn, nrm, yel, (obj->action_description && *obj->action_description) ? obj->action_description : "Not Set.\r\n",
grn, nrm, cyn, buf1,
grn, nrm, cyn, buf2);
/* Send first half then build second half of menu. */
sprintbitarray(GET_OBJ_WEAR(OLC_OBJ(d)), wear_bits, EF_ARRAY_MAX, buf1);
sprintbitarray(GET_OBJ_AFFECT(OLC_OBJ(d)), affected_bits, EF_ARRAY_MAX, buf2);
write_to_output(d,
"%s7%s) Wear flags : %s%s\r\n"
"%s8%s) Weight : %s%d\r\n"
"%s9%s) Cost : %s%d\r\n"
"%sA%s) Cost/Day : %s%d\r\n"
"%sB%s) Timer : %s%d\r\n"
"%sR%s) Repop Pecent: %s%d\r\n"
"%sC%s) Values : %s%d %d %d %d\r\n"
"%sD%s) Applies menu\r\n"
"%sE%s) Extra descriptions menu: %s%s%s\r\n"
"%sM%s) Min Level : %s%d\r\n"
"%sP%s) Perm Affects: %s%s\r\n"
"%sS%s) Script : %s%s\r\n"
"%sW%s) Copy object\r\n"
"%sX%s) Delete object\r\n"
"%sQ%s) Quit\r\n"
"Enter choice : ",
grn, nrm, cyn, buf1,
grn, nrm, cyn, GET_OBJ_WEIGHT(obj),
grn, nrm, cyn, GET_OBJ_COST(obj),
grn, nrm, cyn, GET_OBJ_RENT(obj),
grn, nrm, cyn, GET_OBJ_TIMER(obj),
grn, nrm, cyn, GET_OBJ_REPOP(obj),
grn, nrm, cyn, GET_OBJ_VAL(obj, 0),
GET_OBJ_VAL(obj, 1),
GET_OBJ_VAL(obj, 2),
GET_OBJ_VAL(obj, 3),
grn, nrm, grn, nrm, cyn, obj->ex_description ? "Set." : "Not Set.", grn,
grn, nrm, cyn, GET_OBJ_LEVEL(obj),
grn, nrm, cyn, buf2,
grn, nrm, cyn, OLC_SCRIPT(d) ? "Set." : "Not Set.",
grn, nrm,
grn, nrm,
grn, nrm);
OLC_MODE(d) = OEDIT_MAIN_MENU;
}
In oedit_parse() in oedit.c add the following:
Code:
case 'r':
case 'R':
write_to_output(d, "Enter repop percent (0-100): ");
OLC_MODE(d) = OEDIT_REPOP;
break;
and also add to oedit_parse()
Code:
case OEDIT_REPOP:
GET_OBJ_REPOP(OLC_OBJ(d)) = LIMIT(atoi(arg), 0, MAX_OBJ_REPOP);
break;
In reset_zone() in db.c add the following: (These govern the actual item loading)
Code:
case 'O': /* read an object */
if (obj_index[ZCMD.arg1].number < ZCMD.arg2)
{
obj = read_object(ZCMD.arg1, REAL);
if (ZCMD.arg3 != NOWHERE)
{
rarity = rand_number(0, 99);
if (IS_HAPPYEQ && IS_HAPPYHOUR)
GET_OBJ_REPOP(obj) = MIN(GET_OBJ_REPOP(obj) + HAPPY_EQ, 100);
if (GET_OBJ_REPOP(obj) > rarity)
{
obj_to_room(obj, ZCMD.arg3);
load_otrigger(obj);
last_cmd = 1;
tobj = obj;
}
else
{
extract_obj(obj);
last_cmd = 1;
tobj = obj;
}
}
else
{
obj = read_object(ZCMD.arg1, REAL);
IN_ROOM(obj) = NOWHERE;
last_cmd = 1;
tobj = obj;
}
}
else
last_cmd = 0;
tmob = NULL;
break;
case 'P': /* object to object */
if (obj_index[ZCMD.arg1].number < ZCMD.arg2)
{
obj = read_object(ZCMD.arg1, REAL);
if (!(obj_to = get_obj_num(ZCMD.arg3)))
{
ZONE_ERROR("target obj not found, command disabled");
ZCMD.command = '*';
break;
}
rarity = rand_number(0, 99);
if (IS_HAPPYEQ && IS_HAPPYHOUR)
GET_OBJ_REPOP(obj) = MIN(GET_OBJ_REPOP(obj) + HAPPY_EQ, 100);
if (GET_OBJ_REPOP(obj) > rarity)
{
obj_to_obj(obj, obj_to);
last_cmd = 1;
load_otrigger(obj);
tobj = obj;
}
else
{
extract_obj(obj);
last_cmd = 1;
tobj = obj;
}
}
else
last_cmd = 0;
tmob = NULL;
break;
case 'G': /* obj_to_char */
if (!mob)
{
char error[MAX_INPUT_LENGTH];
snprintf(error, sizeof(error), "attempt to give obj #%d to non-existant mob, command disabled", obj_index[ZCMD.arg1].vnum);
ZONE_ERROR(error);
ZCMD.command = '*';
break;
}
if (obj_index[ZCMD.arg1].number < ZCMD.arg2)
{
obj = read_object(ZCMD.arg1, REAL);
rarity = rand_number(0, 99);
if (IS_HAPPYEQ && IS_HAPPYHOUR)
GET_OBJ_REPOP(obj) = MIN(GET_OBJ_REPOP(obj) + HAPPY_EQ, 100);
if (GET_OBJ_REPOP(obj) > rarity)
{
obj_to_char(obj, mob);
last_cmd = 1;
load_otrigger(obj);
tobj = obj;
}
else
{
extract_obj(obj);
last_cmd = 1;
tobj = obj;
}
}
else
last_cmd = 0;
tmob = NULL;
break;
case 'E': /* object to equipment list */
if (!mob)
{
char error[MAX_INPUT_LENGTH];
snprintf(error, sizeof(error), "trying to equip non-existant mob with obj #%d, command disabled", obj_index[ZCMD.arg1].vnum);
ZONE_ERROR(error);
ZCMD.command = '*';
break;
}
if (obj_index[ZCMD.arg1].number < ZCMD.arg2)
{
obj = read_object(ZCMD.arg1, REAL);
if (ZCMD.arg3 < 0 || ZCMD.arg3 >= NUM_WEARS)
{
char error[MAX_INPUT_LENGTH];
snprintf(error, sizeof(error), "invalid equipment pos number (mob %s, obj %d, pos %d)", GET_NAME(mob), obj_index[ZCMD.arg2].vnum, ZCMD.arg3);
ZONE_ERROR(error);
}
rarity = rand_number(0, 99);
if (IS_HAPPYEQ && IS_HAPPYHOUR)
GET_OBJ_REPOP(obj) = MIN(GET_OBJ_REPOP(obj) + HAPPY_EQ, 100);
if (GET_OBJ_REPOP(obj) > rarity)
{
IN_ROOM(obj) = IN_ROOM(mob);
load_otrigger(obj);
if (wear_otrigger(obj, mob, ZCMD.arg3))
{
IN_ROOM(obj) = NOWHERE;
equip_char(mob, obj, ZCMD.arg3);
}
else
obj_to_char(obj, mob);
tobj = obj;
last_cmd = 1;
}
else
{
extract_obj(obj);
last_cmd = 1;
tobj = obj;
}
}
else
last_cmd = 0;
tmob = NULL;
break;
Add the following to *parse_object() in db.c: (this will break your current item loading, causing a crash on load, unless you add a check to write them correctly beforehand)
Code:
if ((retval = sscanf(line, "%d %d %d %d %d %d", t, t + 1, t + 2, t + 3, t + 4, t + 5)) != 6)
{
if (retval == 4)
{
t[4] = 0;
t[5] = 100;
}
else if (retval == 5)
t[5] = 100;
else
{
log("SYSERR: Format error in third numeric line (expecting 6 args, got %d), %s", retval, buf2);
exit(1);
}
}
GET_OBJ_WEIGHT(obj_proto + i) = t[0];
GET_OBJ_COST(obj_proto + i) = t[1];
GET_OBJ_RENT(obj_proto + i) = t[2];
GET_OBJ_LEVEL(obj_proto + i) = t[3];
GET_OBJ_TIMER(obj_proto + i) = t[4];
GET_OBJ_REPOP(obj_proto + i) = t[5];
obj_proto[i].sitting_here = NULL;
In *obsave_parse_objects() in objsave.c add the following:
Code:
case 'R':
if (!strcmp(tag, "Rare"))
GET_OBJ_REPOP(temp) = num;
In objsave_save_obj_record() in objsave.c add the following:
Code:
if (TEST_OBJN(rarity))
fprintf(fp, "Rare: %d\n", GET_OBJ_REPOP(obj));
In save_objects() in genobj.c add the following fprintf() to add the repop:
Code:
fprintf(fp, "%d %s %s %s %s %s %s %s %s %s %s %s %s\n"
"%d %d %d %d\n"
"%d %d %d %d %d %d\n",
GET_OBJ_TYPE(obj),
ebuf1, ebuf2, ebuf3, ebuf4,
wbuf1, wbuf2, wbuf3, wbuf4,
pbuf1, pbuf2, pbuf3, pbuf4,
GET_OBJ_VAL(obj, 0), GET_OBJ_VAL(obj, 1),
GET_OBJ_VAL(obj, 2), GET_OBJ_VAL(obj, 3),
GET_OBJ_WEIGHT(obj), GET_OBJ_COST(obj),
GET_OBJ_RENT(obj), GET_OBJ_LEVEL(obj), GET_OBJ_TIMER(obj), GET_OBJ_REPOP(obj)
);
Finally, add the repop percentage to do_stat_object() in act.wizard.c
Code:
send_to_char(ch, "Repop Percentage: %d\r\n", GET_OBJ_REPOP(j));
Now that you have object rarity in the game, add it to resets like this:
Code:
Room number: 1212 Room zone: 12
1) Builders : CircleMUD
Z) Zone name : Immortal Complex
L) Lifespan : 99 minutes
B) Bottom of zone : 1200
T) Top of zone : 1299
R) Reset Mode : Normal reset.
F) Zone Flags : NOBITS
M) Level Range : Levels 1 to 105
[Command list]
0 - Load a JuJu Zombie [1299], Max : 2
1 - then Give it the Icy Manipulator [1232], Max : 1
2 - Load a JuJu Zombie [1299], Max : 2
3 - then Give it the Icy Manipulator [1232], Max : 1
4 - <END OF LIST>
N) Insert new command.
E) Edit a command.
D) Delete a command.
Q) Quit
Enter your choice : q
No changes made.
Set the repop percentage on the item to some value X like this:
Code:
-- Item number : [1232]
1) Keywords : icy manipulator
2) S-Desc : the Icy Manipulator
3) L-Desc :-
A crystal ball lies here.
4) A-Desc :-
Not Set.
5) Type : WORN
6) Extra flags : GLOW LIMITED MAGIC BLESS
7) Wear flags : TAKE FACE
8) Weight : 0
9) Cost : 0
A) Cost/Day : 0
B) Timer : 0
R) Repop Pecent: (X value that satisfies your repop %)
C) Values : 0 0 0 0
D) Applies menu
E) Extra descriptions menu: Not Set.
M) Min Level : 0
P) Perm Affects: NOBITS
S) Script : Not Set.
W) Copy object
X) Delete object
Q) Quit
Enter choice : q
The formula for adding percentages is somewhat complex and you can experiment with what value works best for you. It's not as simple as 50% + 50% = 100%, but something like 65% + 65% gets you closer. Play around with the values. If the value is too low, the item won't load on either. If the value is too high, it will always load on the second NPC in the table.
This code is beneficial in other ways, however, as you now have random load chances for any and all equipment in your game.
Hope this helps