# Mud-Lua Interface Generation # Copyright (c) 2002 Abi Brady # --- basic operators ---- int bit_or(int a, int b) = a | b # bitwise or int bit_and(int a, int b) = a & b # bitwise and # --- basic object functions --- object get(string id) = planet->get(id) # looks up the object with specified /id/. if you are in a holoprogram, returns the holoclone of it if any. int getint(object what, string id) = what->get_int(id) # returns integer property /id/ on /what/ or if not present, -1 int getintd(object what, string id, int d) = what->get_int(id, d) # returns integer property /id/ on /what/ or if not present, /d/ object getobj(object what, string id) = what->get_object(id) # returns object property /id/ on /what/ or if not present, nil nilstring getstr(object what, string id) = what->get(id) # returns string property /id/ on /what/ or if not present, nil object owner(object o) = o->owner # returns the object that /o/ is in void unset(protobject what, string id) = what->unset(id) # removes the property /id/ on /what/ void set(protobject what, string id, int val) # sets property /id/ on /what/ to /val/ void set(protobject what, string id, string val) # sets property /id/ on /what/ to /val/ void set(protobject what, string id, object val) # sets property /id/ on /what/ to /val/ void getprops(object what, string pref:0) # returns a table with all the properties on /what/ (only those starting with /pref/ if specified) world children(object what) = *what->children # returns all objects directly in /what/ world players(object player:0) = {if(player) ret=players_visible_to(player); else ret=allplayers();} # returns all players visible to /player/, or all players if /player/ is null. world recchildren(object what) = recchildren(what) # returns all objects in /what/, or in objects in those, etc. world quests() = get_quests() # returns all quests world zone(string what) = { MudObject *z=zones->get(what); if (z) ret = *z->children; else lua_error(L, "nonexistant zone"); } # returns all objects in zone /what/. world zonewithflag(string what, flag f) = { MudObject *o; int i; MudObject *z=zones->get(what); if (!z) lua_error(L, "nonexistant zone"); foreach(z->children, o, i) if (o->get_flag(f)) ret.add(*o); } # returns all objects in zone /what/ which have flag /f/ set. # --- flags --- void setflag(protobject o, flag f, bool v) = o->set_flag(f, v) # sets the flag /f/ on /o/ to /v/ bool getflag(object o, flag f) = o->get_flag(f) # returns 1 if /o/ has flag /f/, otherwise nil. Flag constants look like 'flag.Fixed' bool getpriv(object o, priv f) = o->get_priv(f) # returns 1 if /o/ has priv /f/, otherwise nil. Priv constants look like 'priv.God' # --- advanced object info functions --- bool actionverb(string vn) = { Verb *v = verbs->get(vn); ret = v ? streq(v->get("module"), "action") : 0; } # returns true if the string /vn/ corresponds to a currently existing action bool isa(object o, object c) = o==c || (o && o->get_object("treatas")==c) # returns true if /o/ is /c/ or has treatas set to /c/ int state(object o) = state(o) # returns which state /o/ is in (for doors and containers, 0=open, 1=closed, 2=locked) int privs(object who) = privs_of(who) # returns the effective level that /who/ is at, taking into account remort bool person(object o) = is_player(o) || is_mobile(o) # returns true if /o/ is a player or a mobile bool player(object o) = is_player(o) # returns true if /o/ a player bool mobile(object o) = is_mobile(o) # returns true if /o/ a mobile object mount(object o) = mount(o) # returns the thing /o/ is riding, if any bool naked(object who) = is_naked(who) # returns true if /who/ is naked object leader(object o) = o->follows # returns the object /o/ is following char gender(object o) = o->get("gender")?tolower(o->get("gender")[0]):'?' # returns a one-char string which is 'm', 'f', 'n', 'a', etc, or '?' object getmission(object o) = o # return the mission object for mission with id /o/ object quarters(object of) = quarters(of) # return the quarters belonging to /of/ if any object freequarters(object of) = find_free_quarters(of) # find out whether there are any free quarters referred to by the quarters office /of/ bool inlist(object who, string list) = permitted_access(who, list) # return true if /who/'s id is in the comma-separated list /list/ string rank(object who) = get_long_rank(who) # returns the rank of /who/ as a string. string rankfor(int level) = long_rank(level) # returns the rank corresponding to 'level' # --- contents examination --- object getfloor(object o) = floor(o) # returns the floor of given room object holdsclone(object o, object c) = holds_clone_of(o, c) # if /o/ holds any clones of /c/, return one of them. recurses into containers. object holdsflag(object o, flag f) = get_flagged_object(o, f) # returns true if /o/ holds any object with flag /f/ object holdszone(object o, string z) = holdszone(o, z) # returns any object held by /o/ with zone /z/ bool wearsclone(object o, object c) = wf_wears_clone_of(o, c) # returns true if /o/ wears any clones of /c/ object wearsflag(object o, flag f) = wf_wears_with_flag(o, f) # if /o/ wears any objects with flag /f/ return one of them. otherwise return nil. world allholdsflag(object o, flag f) = { allholdsflag(o, f, ret); } # return all objects recursively in /o/ which have the flag /f/. includes /o/ if applicable. world allwearsflag(object o, flag f) = wf_allwearsflag(o, f) # return all objects recursively in /o/ which have the flag /f/. includes /o/ if applicable. world allholdsclone(object o, object f) = { allholdsclone(o, f, ret); } # return all objects recursively in /o/ which are /f/ or are clones of /f/ world alltreatas(object o, object f) = alltreatas(o, f) # return all objects recursively in /o/ which are /f/ or are clones of /f/ bool contains(object o, object w) = { ret = 0; while (w) { if (w->owner == o) { ret = 1; break; } w = w->owner; } } # returns true if /w/ is in /o/ either directly or via other objects, otherwise false. bool wears(object who, object what) = (what->owner == who && what->get_object(KEY_WORNBY)==who) # return true if /who/ is wearing the actual object /what/ object weapon(object who) = who->get_object(KEY_WIELD) # return the object that /who/ is wielding int armour(object who) = { ret = player_armour(who) + parmour(who); } #returns the total value of armour worn by /who/, plus their natural armour string nation(object what) = nation(what) # returns the nation of /what/ # --- financial ---- void pay(object from, object to, int amount, object cur:0) = pay(from, to, amount, cur) # pay /amount/ units in /cur/ from /from/ to /to/ void dofine(object mob, object victim, int amount, object cur:0) = dofine(mob, victim, amount, cur) # pay /amount/ units in /cur/ from /from/ to /to/ object currency(object o) = currency(o) # returns the preferred currency that /o/ uses world currencies() = get_currencies() int convert(int amt, nilobject from, nilobject to) = convertcash(amt, from, to) # convert /amt/ from /from/ to /to/. if /from/ or /to/ is nil, this means ICUs string formatcash(int amt, object o, bool l:0) = formatcash(amt, o, l) # format /amt/ which is denominated in /o/. l can be 1 to indicate long format int cash(object o, object cur) = cash(o, cur) # obtain the amount of /cur/ that /o/ is carrying void setcash(object o, object cur, int amt) = set_cash(o, cur, amt) # set the amount of /cur/ that /o/ is carrying to /amt/ int balance(object o, object cur) = balance(o, cur) # obtain the /cur/ balance of /o/ void setbalance(object o, object cur, int amt) = set_balance(o, cur, amt) # set the /cur/ balance of /o/ to /amt/ void givecash(object who, int amount, object curr) = set_cash(who, curr, cash(who, curr)+amount) # give /who/ /amount/ in /curr/ void wipecash(object who) = wipe_cash(who) # kill all cash held by /who/ void fine(object who, int amount, string why, object jur:0) = fine(who, amount, why, jur) # place a fine on /who/, value of /amount/ ICUs, with /why/ on their record in /jur/ if specified, otherwise the jurisdiction of the room they are in. object jurisdiction(object where) = jurisdiction(where) # return the jurisdiction that applies in /where/ # --- utility --- string formattime(object who, string format, int when) = sstrftime(who, format, when) # format /when/ (a time_t value) with /format/ (same as strftime uses) using timezone that /who/ has asked for string formatduration(int when, bool nosecs:0) = {when +=(unsigned int)now; ret=howsoon(when,nosecs);} #converts a duration in seconds to a string: "x days x hours x minutes x seconds". If nosecs is true, seconds will not be returned. int value(object o) = object_value(o) # how much is /o/ worth in ICUs string capitalise(string what) = ssprintf("%#s", what) # capitalise the given string string pad(string what, int width) = ssprintf("%-*s", width, what) # pad the given string to /width/ spaces. bear in mind colourcodes and doublewidth characters, etc. string name(string id) = lookup_name(id).c_str() # returns the colour and capitalised name of the player with /id/, who need not be logged in void swap(object a, object b) = { MudObject *o = b->owner; set_owner(b, a->owner); set_owner(a, o); } # swap /a/ and /b/'s owners. int random(int range) = random_number(range) # returns number between 0 and /range/-1 int mudhour(object room) = mudtime(room).hour # returns mud-time hour between 0 and 23 for /room/ int mudminute(object room) = mudtime(room).min # returns mud-time minute between 0 and 59 for /room/ int now() = (unsigned int)now # returns the current time, in seconds, since 1970 object wornon(object who, string where) = { MudObject *a=worn_on(who, where, 0); MudObject *b=wornfrom(who)?worn_on(wornfrom(who), where, 0):NULL; if (b && !a) ret = b; else if (b && a && b->get_int("wornlevel", 0)>(a->get_int("wornlevel", 0))) ret = b; else ret = a; } # returns the outermost clothing worn by /who/ on their /where/ world clothing(object who) = clothes(who) #returns all clothing worn by /who/ void flush(object o) = o->push_data() # cause current buffer of /o/ to be sent to them. void mplex_flush(player p) = { if (p->p && p->p->mplex && !p->p->mxp) p->push_data(); } # flush data for the purposes of mplexing void mplex_choose(player p, int i) = { if (p->p) if (p->p->mxp) { if (i) p->printf("\3dest Sub X=1 Y=1\4"); else p->printf("\3/dest\4"); } else p->p->mplex_choose(i); } # sends the code to choose multiplexed connection /i/ on /o/. 1 is subwindow for games, 0 is main window. void mplex_setsize(player p, int i, int cols, int rows) = { if (p->p) if (p->p->mxp) p->printf("\3frame name=\"Sub\" floating height=\"%ic\" width=\"%ic\"\4", rows+1, cols); else p->p->mplex_setsize(i, cols, rows); } # sets the size of the subwindow /i/ on /o/ to /cols/ by /rows/. void mplex_roomupdate(object o) = mplex_update(o) # call the 'mplex' trap on the room for everyone in it who has mplex support. bool dotrap(string a, object pl, object o1, object o2:0, object on:0, object o3:0) = dotrap(a, pl, o1, o2, o3, 0, 0, on) # call the lua trap /a/ on /on/ (or /o1/ of /on/ not specified) with o1 /o1/, o2 /o2/ (optional; if not then NULL) and pl /pl/. no txt support yet int super() = { ret = 0; if (sec_on) if (MudObject *sup = sec_on->get_object("treatas")) ret = dotrap(sec_prop, sec_pl, sec_o1, sec_o2, sec_o3, sec_txt, 0, sup); } # call the trap on the treatas that this trap has overridden string format_roomname(object room, object play, string ic, string oc, string sin) = format_roomname(room, play, ic, oc, sin).c_str() # return preposition-prefixed form of /room/'s name, from the pov of /play/, with /ic/ and /oc/ as colourcodes for the name, and /sin/ either "" for normal, or "to" for to-mode (in muon's bar -> to muon's bar, on foo -> onto foo). int mass_within(object o) = mass_used_in_grams(o) # return the mass of the children of /o/ recursively, in grams bool candock(object who, object port) = has_rights(who, port) # return true if player /who/ has the clearance to land at the given dock. bool canattack(object who, object what) = can_attack(who, what) # return true is /who/ can attack /what/ without getting arrested # --- output --- string lang(string txt, object who) = lang(txt, who) # translates the text /txt/ according to the language /who/ is speaking string drunkify(object who, string txt) = possibly_drunkify(who, txt) # mangle the text /txt/ to make it as spoken by /who/. Does slurring, mog conversion, literacy filter, etc. void send(object what, string txt) = what->printf("%s%s", txt, strchr(txt, '\n')?"":"\n") # send /txt/ to /what/. newline not needed. void sendr(object what, string txt) = send_room(what, txt) # send /txt/ to everything in the room /what/ and linked rooms void others(object what, string txt, object what2:0) = { if (!what2) {what->oprintf("%s%s", txt, strchr(txt, '\n')?"":"\n");} else {what->oprintf(avoid(what2), "%s\n", txt);} } # send /txt/ to everything in the same room as /what/. newline not needed. void act(object what, string txt, nilobject target:0, nilobject prop:0, string arg:0) = { if (!prop) prop = target; what->action(target, txt, arg, prop); what->action_to(target, txt, arg, prop); if (target) { target->action_from(what, txt, arg, NULL, prop); } } #uses /txt/ as the text of an action and performs it as /what/. %1 appears to be "you" to what. If specified /target/ and /prop/ are used. string acts(object what, string txt, nilobject target:0, nilobject prop:0, string txt2:0) = { if (!prop) prop = target; ret=sprinta(NULL, txt, what, target, txt2, 1, prop); } # format /txt/ as if it were an action string performed by /what/ void oact(object what, string txt, nilobject target:0, nilobject prop:0, string arg:0) = { if (!prop) prop = target; what->action(target, txt, arg, prop); if (target) { target->action_from(what, txt, arg, NULL, prop); } } #uses /txt/ as the text of an action and performs it as /what/. doesn't get sent to /what/. If specified, /target/ and /prop/ are used. string acts2(object observer, object what, string txt, nilobject target:0, nilobject prop:0, string txt2:0) = { if (!prop) prop = target; ret=sprinta(observer, txt, what, target, txt2, 2, prop); } # format /txt/ as if it were an action string performed by /what/, from the point of view of /observer/ void tell(object who, object to, string msg) = who->interpretf("tell %s %s", to->id, msg) #tell /to/ /msg/ from /who/ void say(object who, string msg) = who->interpretf("say %s", msg) # makes /who/ say /msg/ void sendzone(string zone, string txt) = zone_send(zone, 0, txt) # send /txt/ to all players in rooms with zone /zone/ void sendzonebut(string zone, object notr, string txt) = zone_send(zone, notr, txt) # send /txt/ to all players in rooms with zone /zone/, except for those in /not/ string describe(world o) = magiclist(o) # return a string describing the objects in /o/, for example "two trees, eleven jellybabies and a helicopter" # --- basic object manipulation --- void vanish(protobject o) = vanish(o) #if /o/ is a clone, delete, if not move to "empty" void vanish_all(protobject o) = vanish_all(o) # vanish /o/ and all objects in it, recursively string plural_name(object what) = plural_name(what, 1) #returns the plural form of /what/'s name string remove_articles(string txt) = remove_articles(txt) #returns /txt/, minus leading articles void empty_ship(protobject o) = empty_ship(o) # empties the ship /o/ of all players void move(protobject what, object where) = set_owner(what, where) # moves /what/ to be in /where/ object clone(object what, object where, object mis:0) = { ret = clone_object(what, where, NULL); Mission *m = dynamic_cast<Mission*>(mis); if (ret && mis) ret->set_mission(m); } # clones a /what/ and places it in /where/ object autoclone(object what, object where, string zone) = clone_object(what, where, NULL, 1, zone) # clones a /what/ and places it in /where/. creates auto objects too. everything'll be part of /zone/ object clone_ship(object what, object mission) = clone_ship(what, dynamic_cast<Mission*>(mission)) # clones ship template /what/ for /mission/ void reset(protobject what) = what->reset() # resets /what/ to its starting conditions bool once(protobject o) = {ret = o->get_int("initstate",0) == state(o);o->set(KEY_STATE, !o->get_int("initstate",0));} # first time it is run on /o/ will return 1, from then on will return 0 until object reset void setstate(protobject what, int n) = what->set(KEY_STATE, n) # sets /what/ to be in state /n/ object anyplayerfrom(object blah) = choose_random_player_from(blah) # return a random player from /blah/ object anyobjectfrom(object blah) = choose_random_object_from(blah) # return a random object from /blah/ object anyroominzone(string zone) = random_room_from_zone(zone) # returns a random room from /blah/ string anyshipname() = random_shipname() # return a random civilian ship name string anywarshipname() = random_warshipname() # return a random warship name object mission(object blah) = (MudObject*)blah->mission # returns the minimission that owns /blah/ void setmission(object obj, object mis) = obj->set_mission(dynamic_cast<Mission*>(mis)) # associates the object /obj/ with the minimission /mis/. The object will be destroyed with the minimission. void clearmission(object obj) = obj->set_mission(0) # makes /obj/ a freestanding object that isn't associated with a mission void name_mobile(object mob) = name_mobile(mob) # give /mob/ a random human name world match(object who, table arg) = match(who, arg.argc, arg.argv, NULL, LOOK_BOTH|LOOK_MWIELD); # try to match /arg/ from the point of view of /who/ world matchprep(object who, table arg, string prep) = match(who, arg.argc, arg.argv, NULL, LOOK_BOTH|LOOK_MWIELD, prep); # try to match /arg/ from the point of view of /who/, looking for /prep/ object matchplayer(object who, string str) = get_player(who, str) # try to match /str/ to a person, from the point of view of /who/ bool prep(string cand) = prep(cand); #returns true if /cand/ is in the valid prepositions list. # --- advanced object manipulation --- void give(protobject from, object what, object dest) = give(from, what, dest) #makes /from/ give /what/ to /dest/ void startfight(object attack, object victim) = attack->interpretf("kill %s", victim->id) #makes /attack/ start a fight with /victim/ void interpret(protobject what, string cmd) = what->interpret2(cmd) #does /cmd/ as /what/ void interpret2(protobject what, string cmd) = what->interpret2(cmd) #does /cmd/ as /what/ with full privs object kill(object who, nilstring msg) = do_die(who, 5*privs_of(who), msg) #make /blah/ die, with log message /msg/ (which can be nil). returns the corpse if any, which you should set a cause of death on. world killr(object room, nilstring msg) = { MudObject *o; int i; foreach(room->children, o, i) if (is_player(o) || is_mobile(o)) { MudObject *corpse = do_die(o, 5*privs_of(o), msg); ret.add(corpse); if (o->owner!=room) i--; } } # kill everything in /room/ with message /msg/ void heal(object medic, object who, int amount) = heal(medic, who, amount) # make /medic/ heal /who/ up to /amount/ health points. void harm(object who, int amount) = set_strength(who, strength_of(who) - amount) # remove /amount/ health points from /who/ void syslog(priv pfl, string cat, object who, string msg) = log(who, pfl, 0, cat, "%s", msg) # --- quest related stuff --- void givequest(object who, object mis) = complete_mission(who, mis) # grant /who/ the /id/ quest with a cash reward void grudgequest(object who, object mis) = grudge_mission(who, mis) # grant /who/ the /id/ quest but without any cash reward void failquest(object who, object mis) = fail_mission(who, mis) # mark /who/ as having failed the /id/ quest bool accepted(object who, object quest) = {MudObject *mis = who->get_object("mission"); ret = (mis && mis->get_object("!accepter") == who && (mis==quest || (mis->get_object("instance")==quest))); } # return true if /who/ has accepted /quest/ bool donemission(object who, object quest) = quest_done(who, quest) # return true if /who/ has done mission with qid /quest/ void givemission(object who, object mission) = complete_mission(who, mission) # make /who/ have done the minimission /mission/, reward them, message, etc. void failmission(object who, object o) = fail_mission(who, o) # mark /who/ as having failed the given minimission # --- slightly evil stuff --- void startpager(player who) = ldivert(who, "autolua") # start the pager on /who/. all further output sent to them will be send instead to a file and then paged back to them later. void endpager(player who) = lundivert(who, "autolua") # activate the pager upon /who/. done automatically if not done in a trap. string addtimer(protobject what, string code, int when) = addtimer(what, code, when) # make /what/ execute /code/ in /when/ seconds time. will run under the security context of the calling code. void canceltimer(string code) = removetimer(code) string type(void something) # returns "nil", "number", "string", "table", "function" or "userdata", depending on /something/. string toascii(string w) = msi_colourfilter?msi_colourfilter(NULL, w, asc_cols):"" # strip colour codes and latin1 or unicode characters from /w/, making is plain ascii void arrest(object crim, object victim, string help) = arrest(crim, victim, help) # /victim/ will cry /help/ on the intercom. this will cause the arrest of /crim/ if in policed area. bool dead(object what) = what->owner == planet->get("dead") # return true if /what/ is dead string id(object what) = what->id # returns the id of /what/.