Drunks Database (#1200)(an instance of Generic Database made by Dred)     A database that keeps track of all drunks globally and also stores all messages displayed to them as they drink and sober up. Go to location of this object, Cluttered Closet. VERB SOURCE CODE: get_drunk:
if (!$perm_utils:controls(caller_perms(), this))
return E_PERM;
endif
who = args[1];
for d in (this.limits)
drunks = this:find(tostr("upto", d));
if (fnd = $list_utils:assoc(who, drunks))
return {d, @fnd};
endif
endfor
return 0;
.
add_drunk:
if (!$perm_utils:controls(caller_perms(), this))
return E_PERM;
endif
who = args[1];
amt = args[2];
if (data = this:get_drunk(who))
data[3] = data[3] + amt;
ind = data[1];
this:rem_d(tostr("upto", ind), who);
if (ind == this.limits[length(this.limits)])
elseif (tonum(data[3]) > tonum(ind))
f = ind in this.limits;
ind = this.limits[f + 1];
endif
this:add_d(tostr("upto", ind), data[2..length(data)]);
else
this.drunks = setadd(this.drunks, who);
this:add_d(tostr("upto", this.limits[1]), {who, amt, time()});
this:sobering();
endif
.
add_d rem_d:
if (!$perm_utils:controls(caller_perms(), this))
return E_PERM;
endif
key = args[1];
data = args[2];
drunks = this:find(key);
if (verb == "add_d")
drunks = setadd(drunks, data);
else
ind = $list_utils:iassoc(data, drunks);
drunks = listdelete(drunks, ind);
endif
this:insert(key, drunks);
.
rem_drunk:
if (!$perm_utils:controls(caller_perms(), this))
return E_PERM;
endif
who = args[1];
amt = args[2];
if (data = this:get_drunk(who))
data[3] = data[3] - amt;
ind = data[1];
this:rem_d(tostr("upto", ind), who);
if (data[3] <= 0)
this.drunks = setremove(this.drunks, who);
return;
elseif (ind == this.limits[1])
elseif (ind == "inf")
ind = (data[3] <= 1500) ? "1500" | "inf";
elseif (tonum(data[3]) < tonum(newind = this.limits[(ind in this.limits) - 1]))
ind = newind;
endif
this:add_d(tostr("upto", ind), data[2..length(data)]);
endif
.
drink_eff:
if (!$perm_utils:controls(caller_perms(), this))
return E_PERM;
endif
drink = args[1];
con_verb = args[2];
amt = args[3];
delay = args[4];
if ($object_utils:isa(drink, this.drinkable_root) && drink.nonalc)
return;
endif
this:add_drunk(player, amt);
if (result = this:get_drunk(player))
lvl = result[1];
if (result[3] > 80)
fork (delay)
this:display_eff(player, this.levels[lvl in this.limits]);
endfork
endif
else
"Eeek. Shouldn't happen.";
endif
.
display_eff:
":display_eff(OBJ who to, STR category key to get data from, [NUM flag to display
definitely. None or 0 to use percentage]) => displays effects messages.";
if (caller != this)
return E_PERM;
endif
who = args[1];
which = args[2];
flag = (length(args) > 2) ? args[3] | 0;
if (((random(10) <= 6) || flag) && $object_utils:connected(who))
effx = this:find(which);
oeffx = this:find(tostr("o", which));
if (mess = effx[random(length(effx))])
who:tell(mess);
endif
if ($object_utils:has_callable_verb(who.location, "announce") && (mess = oeffx[random(length(oeffx))]))
who.location:announce($string_utils:pronoun_sub(mess, who));
endif
endif
.
sobering:
if (!$perm_utils:controls(caller_perms(), this))
return E_PERM;
endif
if ($code_utils:task_valid(this.sober_task))
return;
endif
fork task (0)
while (this.active && this.drunks)
for lush in (this.drunks)
if (result = this:get_drunk(lush))
if ((time() - result[4]) > this.sober_delay)
this:rem_drunk(lush, this.sober_amt);
if ((!(newres = this:get_drunk(lush))) || (newres[1] != result[1]))
this:display_eff(lush, "sober", 1);
endif
endif
else
this.drunks = setremove(this.drunks, lush);
endif
$command_utils:suspend_if_needed(0);
endfor
suspend(this.sober_delay);
endwhile
endfork
this.sober_task = task;
.
PROPERTY DATA:       u       upto1       l       s       o       ol       os       limits       levels       drunks       sober_task       sober_delay       active       sober_amt       drinkable_root |