mux/src/levels.cpp

Go to the documentation of this file.
00001 #ifdef REALITY_LVLS
00002 /*
00003  * levels.cpp - Reality levels stuff
00004  */
00005 
00006 #include "copyright.h"
00007 #include "autoconf.h"
00008 #include "config.h"
00009 
00010 #include "externs.h"
00011 #include "db.h"
00012 #include "attrs.h"
00013 #include "mudconf.h"
00014 #include "command.h"
00015 #include "powers.h"
00016 #include "alloc.h"
00017 #include "match.h"
00018 #include "levels.h"
00019 #include "stringutil.h"
00020 
00021 extern void cf_log_notfound(dbref, char *, const char *, char *);
00022 
00023 RLEVEL RxLevel(dbref thing)
00024 {
00025     const char *buff = atr_get_raw(thing, A_RLEVEL);
00026     if (  NULL == buff
00027        || strlen(buff) != 17)
00028     {
00029         switch(Typeof(thing))
00030         {
00031         case TYPE_ROOM:
00032             return(mudconf.def_room_rx);
00033 
00034         case TYPE_PLAYER:
00035             return(mudconf.def_player_rx);
00036 
00037         case TYPE_EXIT:
00038             return(mudconf.def_exit_rx);
00039 
00040         default:
00041             return(mudconf.def_thing_rx);
00042         }
00043     }
00044 
00045     int i;
00046     RLEVEL rx = 0;
00047     for (i = 0; mux_ishex(buff[i]); i++)
00048     {
00049         rx = 16 * rx + mux_hex2dec(buff[i]);
00050     }
00051     return rx;
00052 }
00053 
00054 RLEVEL TxLevel(dbref thing)
00055 {
00056     const char *buff = atr_get_raw(thing, A_RLEVEL);
00057     if (  NULL == buff
00058        || strlen(buff) != 17)
00059     {
00060         switch(Typeof(thing))
00061         {
00062         case TYPE_ROOM:
00063             return(mudconf.def_room_tx);
00064 
00065         case TYPE_PLAYER:
00066             return(mudconf.def_player_tx);
00067 
00068         case TYPE_EXIT:
00069             return(mudconf.def_exit_tx);
00070 
00071         default:
00072             return(mudconf.def_thing_tx);
00073         }
00074     }
00075 
00076     // Skip the first field.
00077     //
00078     int i;
00079     for (i = 0; buff[i] && !mux_isspace(buff[i]); i++)
00080     {
00081         ; // Nothing.
00082     }
00083 
00084     RLEVEL tx = 0;
00085     if (buff[i])
00086     {
00087         // Skip space found above.
00088         //
00089         i++;
00090 
00091         // Decode second field.
00092         //
00093         for ( ; mux_ishex(buff[i]); i++)
00094         {
00095             tx = 16 * tx + mux_hex2dec(buff[i]);
00096         }
00097     }
00098     return tx;
00099 }
00100 
00101 void notify_except_rlevel
00102 (
00103     dbref loc,
00104     dbref player,
00105     dbref exception,
00106     const char *msg,
00107     int xflags
00108 )
00109 {
00110     if (  loc != exception
00111        && IsReal(loc, player))
00112     {
00113         notify_check(loc, player, msg,
00114             (MSG_ME_ALL | MSG_F_UP | MSG_S_INSIDE | MSG_NBR_EXITS_A| xflags));
00115     }
00116 
00117     dbref first;
00118     DOLIST(first, Contents(loc))
00119     {
00120         if (  first != exception
00121            && IsReal(first, player))
00122         {
00123             notify_check(first, player, msg,
00124                 (MSG_ME | MSG_F_DOWN | MSG_S_OUTSIDE | xflags));
00125         }
00126     }
00127 }
00128 
00129 void notify_except2_rlevel
00130 (
00131     dbref loc,
00132     dbref player,
00133     dbref exc1,
00134     dbref exc2,
00135     const char *msg
00136 )
00137 {
00138     if (  loc != exc1
00139        && loc != exc2
00140        && IsReal(loc, player))
00141     {
00142         notify_check(loc, player, msg,
00143             (MSG_ME_ALL | MSG_F_UP | MSG_S_INSIDE | MSG_NBR_EXITS_A));
00144     }
00145 
00146     dbref first;
00147     DOLIST(first, Contents(loc))
00148     {
00149         if (  first != exc1
00150            && first != exc2
00151            && IsReal(first, player))
00152         {
00153             notify_check(first, player, msg,
00154                 (MSG_ME | MSG_F_DOWN | MSG_S_OUTSIDE));
00155         }
00156     }
00157 }
00158 
00159 void notify_except2_rlevel2
00160 (
00161     dbref loc,
00162     dbref player,
00163     dbref exc1,
00164     dbref exc2,
00165     const char *msg
00166 )
00167 {
00168     if (  loc != exc1
00169        && loc != exc2
00170        && IsReal(loc, player))
00171     {
00172         notify_check(loc, player, msg,
00173             (MSG_ME_ALL | MSG_F_UP | MSG_S_INSIDE | MSG_NBR_EXITS_A));
00174     }
00175 
00176     dbref first;
00177     DOLIST(first, Contents(loc))
00178     {
00179         if (  first != exc1
00180            && first != exc2
00181            && IsReal(first, player)
00182            && IsReal(first, exc2))
00183         {
00184             notify_check(first, player, msg,
00185                 (MSG_ME | MSG_F_DOWN | MSG_S_OUTSIDE));
00186         }
00187     }
00188 }
00189 
00190 /*
00191  * ---------------------------------------------------------------------------
00192  * * rxlevel_description: Return an mbuf containing the RxLevels of the thing.
00193  */
00194 
00195 char *rxlevel_description(dbref player, dbref target)
00196 {
00197     // Allocate the return buffer.
00198     //
00199     int  otype = Typeof(target);
00200     char *buff = alloc_mbuf("rxlevel_description");
00201     char *bp   = buff;
00202 
00203     int i;
00204     RLEVEL rl = RxLevel(target);
00205     for (i = 0; i < mudconf.no_levels; ++i)
00206     {
00207         if (  (rl & mudconf.reality_level[i].value)
00208            == mudconf.reality_level[i].value)
00209         {
00210             safe_mb_chr(' ', buff, &bp);
00211             safe_mb_str(mudconf.reality_level[i].name, buff, &bp);
00212         }
00213     }
00214 
00215     // Terminate the string, and return the buffer to the caller.
00216     //
00217     *bp = '\0';
00218     return buff;
00219 }
00220 
00221 /*
00222  * ---------------------------------------------------------------------------
00223  * * txlevel_description: Return an mbuf containing the TxLevels of the thing.
00224  */
00225 
00226 char *txlevel_description(dbref player, dbref target)
00227 {
00228     // Allocate the return buffer.
00229     //
00230     int otype = Typeof(target);
00231     char *buff = alloc_mbuf("txlevel_description");
00232     char *bp = buff;
00233 
00234     int i;
00235     RLEVEL tl = TxLevel(target);
00236     for (i = 0; i < mudconf.no_levels; ++i)
00237     {
00238         if (  (tl & mudconf.reality_level[i].value)
00239            == mudconf.reality_level[i].value)
00240         {
00241             safe_mb_chr(' ', buff, &bp);
00242             safe_mb_str(mudconf.reality_level[i].name, buff, &bp);
00243         }
00244     }
00245 
00246     // Terminate the string, and return the buffer to the caller.
00247     //
00248     *bp = '\0';
00249     return buff;
00250 }
00251 
00252 RLEVEL find_rlevel(char *name)
00253 {
00254     for (int i = 0; i < mudconf.no_levels; i++)
00255     {
00256         if (mux_stricmp(name, mudconf.reality_level[i].name) == 0)
00257         {
00258             return mudconf.reality_level[i].value;
00259         }
00260     }
00261     return 0;
00262 }
00263 
00264 void do_rxlevel
00265 (
00266     dbref player,
00267     dbref cause,
00268     dbref enactor,
00269     int   nargs,
00270     int   key,
00271     char *object,
00272     char *arg
00273 )
00274 {
00275     if (!arg || !*arg)
00276     {
00277         notify_quiet(player, "I don't know what you want to set!");
00278         return;
00279     }
00280 
00281     // Find thing.
00282     //
00283     dbref thing = match_controlled(player, object);
00284     if (NOTHING == thing)
00285     {
00286         return;
00287     }
00288 
00289     char lname[9];
00290     RLEVEL ormask = 0;
00291     RLEVEL andmask = ~ormask;
00292     while (*arg)
00293     {
00294         int negate = 0;
00295         while (  *arg != '\0'
00296               && mux_isspace(*arg))
00297         {
00298             arg++;
00299         }
00300 
00301         if (*arg == '!')
00302         {
00303             negate = 1;
00304             ++arg;
00305         }
00306 
00307         int i;
00308         for (i = 0; *arg && !mux_isspace(*arg); arg++)
00309         {
00310             if (i < 8)
00311             {
00312                 lname[i++] = *arg;
00313             }
00314         }
00315 
00316         lname[i] = '\0';
00317         if (!lname[0])
00318         {
00319             if (negate)
00320             {
00321                 notify(player, "You must specify a reality level to clear.");
00322             }
00323             else
00324             {
00325                 notify(player, "You must specify a reality level to set.");
00326             }
00327             return;
00328         }
00329 
00330         RLEVEL result = find_rlevel(lname);
00331         if (!result)
00332         {
00333             notify(player, "No such reality level.");
00334             continue;
00335         }
00336         if (negate)
00337         {
00338             andmask &= ~result;
00339             notify(player, "Cleared.");
00340         }
00341         else
00342         {
00343             ormask |= result;
00344             notify(player, "Set.");
00345         }
00346     }
00347 
00348     // Set the Rx Level.
00349     //
00350     char *buff = alloc_lbuf("do_rxlevel");
00351     sprintf(buff, "%08X %08X", RxLevel(thing) & andmask | ormask, TxLevel(thing));
00352     atr_add_raw(thing, A_RLEVEL, buff);
00353     free_lbuf(buff);
00354 }
00355 
00356 void do_txlevel
00357 (
00358     dbref player,
00359     dbref cause,
00360     dbref enactor,
00361     int nargs,
00362     int key,
00363     char *object,
00364     char *arg
00365 )
00366 {
00367     if (!arg || !*arg)
00368     {
00369         notify_quiet(player, "I don't know what you want to set!");
00370         return;
00371     }
00372 
00373     // Find thing.
00374     //
00375     dbref thing = match_controlled(player, object);
00376     if (NOTHING == thing)
00377     {
00378         return;
00379     }
00380 
00381     char lname[9];
00382     RLEVEL ormask = 0;
00383     RLEVEL andmask = ~ormask;
00384     while (*arg)
00385     {
00386         int negate = 0;
00387         while (  *arg
00388               && mux_isspace(*arg))
00389         {
00390             arg++;
00391         }
00392 
00393         if (*arg == '!')
00394         {
00395             negate = 1;
00396             ++arg;
00397         }
00398 
00399         int i;
00400         for (i = 0; *arg && !mux_isspace(*arg); arg++)
00401         {
00402             if (i < 8)
00403             {
00404                 lname[i++] = *arg;
00405             }
00406         }
00407 
00408         lname[i] = '\0';
00409         if (!lname[0])
00410         {
00411             if (negate)
00412             {
00413                 notify(player, "You must specify a reality level to clear.");
00414             }
00415             else
00416             {
00417                 notify(player, "You must specify a reality level to set.");
00418             }
00419             return;
00420         }
00421 
00422         RLEVEL result = find_rlevel(lname);
00423         if (!result)
00424         {
00425             notify(player, "No such reality level.");
00426             continue;
00427         }
00428         if (negate)
00429         {
00430             andmask &= ~result;
00431             notify(player, "Cleared.");
00432         }
00433         else
00434         {
00435             ormask |= result;
00436             notify(player, "Set.");
00437         }
00438     }
00439 
00440     // Set the Tx Level.
00441     //
00442     char *buff = alloc_lbuf("do_rxlevel");
00443     sprintf(buff, "%08X %08X", RxLevel(thing), TxLevel(thing) & andmask | ormask);
00444     atr_add_raw(thing, A_RLEVEL, buff);
00445     free_lbuf(buff);
00446 }
00447 
00448 /*
00449  * ---------------------------------------------------------------------------
00450  * * decompile_rlevels: Produce commands to set reality levels on target.
00451  */
00452 
00453 void decompile_rlevels(dbref player, dbref thing, char *thingname)
00454 {
00455     char *buf = rxlevel_description(player, thing);
00456     notify(player, tprintf("@rxlevel %s=%s", strip_ansi(thingname), buf));
00457     free_mbuf(buf);
00458 
00459     buf = txlevel_description(player, thing);
00460     notify(player, tprintf("@txlevel %s=%s", strip_ansi(thingname), buf));
00461     free_mbuf(buf);
00462 }
00463 
00464 int *desclist_match(dbref player, dbref thing)
00465 {
00466     static int descbuffer[33];
00467 
00468     descbuffer[0] = 1;
00469     RLEVEL match = RxLevel(player) & TxLevel(thing);
00470     for (int i = 0; i < mudconf.no_levels; i++)
00471     {
00472         if (  (match & mudconf.reality_level[i].value)
00473            == mudconf.reality_level[i].value)
00474         {
00475             ATTR *at = atr_str(mudconf.reality_level[i].attr);
00476             if (at)
00477             {
00478                 int j;
00479                 for (j = 1; j < descbuffer[0]; j++)
00480                 {
00481                     if (at->number == descbuffer[j])
00482                     {
00483                         break;
00484                     }
00485                 }
00486                 if (j == descbuffer[0])
00487                 {
00488                     descbuffer[descbuffer[0]++] = at->number;
00489                 }
00490             }
00491         }
00492     }
00493     return descbuffer;
00494 }
00495 
00496 /* ---------------------------------------------------------------------------
00497  * did_it_rlevel: Have player do something to/with thing, watching the
00498  * attributes. 'what' is actually ignored, the desclist match being used
00499  * instead.
00500  */
00501 void did_it_rlevel
00502 (
00503     dbref player,
00504     dbref thing,
00505     int what,
00506     const char *def,
00507     int owhat,
00508     const char *odef,
00509     int awhat,
00510     char *args[],
00511     int nargs
00512 )
00513 {
00514     char *d, *buff, *act, *charges, *bp, *str;
00515     dbref loc, aowner;
00516     int num, aflags;
00517     int i, *desclist, found_a_desc;
00518 
00519     char *preserve[MAX_GLOBAL_REGS];
00520     int  preserve_len[MAX_GLOBAL_REGS];
00521     bool need_pres = false;
00522 
00523     // Message to player.
00524     //
00525     if (what > 0)
00526     {
00527         // Get description list.
00528         //
00529         desclist = desclist_match(player, thing);
00530         found_a_desc = 0;
00531         for (i = 1; i < desclist[0]; i++)
00532         {
00533             // Ok, if it's A_DESC, we need to check against A_IDESC.
00534             //
00535             if (  A_IDESC == what
00536                && desclist[i] == A_DESC)
00537             {
00538                 d = atr_pget(thing, A_IDESC, &aowner, &aflags);
00539             }
00540             else
00541             {
00542                 d = atr_pget(thing, desclist[i], &aowner, &aflags);
00543             }
00544             if (*d)
00545             {
00546                 // No need for the 'def' message.
00547                 //
00548                 found_a_desc = 1;
00549                 if (!need_pres)
00550                 {
00551                     need_pres = true;
00552                     save_global_regs("did_it_save", preserve, preserve_len);
00553                 }
00554                 buff = bp = alloc_lbuf("did_it.1");
00555                 str = d;
00556                 mux_exec(buff, &bp, thing, thing, player,
00557                     EV_EVAL | EV_FIGNORE | EV_TOP, &str, args, nargs);
00558                 *bp = '\0';
00559 
00560                 if (  A_HTDESC == desclist[i]
00561                    && Html(player))
00562                 {
00563                     safe_str("\r\n", buff, &bp);
00564                     *bp = '\0';
00565                     notify_html(player, buff);
00566                 }
00567                 else
00568                 {
00569                     notify(player, buff);
00570                 }
00571                 free_lbuf(buff);
00572             }
00573             free_lbuf(d);
00574         }
00575         if (!found_a_desc)
00576         {
00577             // No desc found... try the default desc (again).
00578             // A_DESC or A_HTDESC... the worst case we look for it twice.
00579             //
00580             d = atr_pget(thing, what, &aowner, &aflags);
00581             if (*d)
00582             {
00583                 // No need for the 'def' message
00584                 //
00585                 found_a_desc = 1;
00586                 if (!need_pres)
00587                 {
00588                     need_pres = true;
00589                     save_global_regs("did_it_save", preserve, preserve_len);
00590                 }
00591                 buff = bp = alloc_lbuf("did_it.1");
00592                 str = d;
00593                 mux_exec(buff, &bp, thing, thing, player,
00594                     EV_EVAL | EV_FIGNORE | EV_TOP, &str, args, nargs);
00595                 *bp = '\0';
00596 
00597                 if (  A_HTDESC == what
00598                    && Html(player))
00599                 {
00600                     safe_str("\r\n", buff, &bp);
00601                     *bp = '\0';
00602                     notify_html(player, buff);
00603                 }
00604                 else
00605                 {
00606                     notify(player, buff);
00607                 }
00608                 free_lbuf(buff);
00609             }
00610             else if (def)
00611             {
00612                 notify(player, def);
00613             }
00614             free_lbuf(d);
00615         }
00616     }
00617     else if (  what < 0
00618             && def)
00619     {
00620         notify(player, def);
00621     }
00622 
00623     if (isPlayer(thing))
00624     {
00625        d = atr_pget(mudconf.master_room, get_atr("ASSET_DESC"), &aowner, &aflags);
00626        if (*d)
00627        {
00628           if (!need_pres)
00629           {
00630              need_pres = true;
00631              save_global_regs("did_it_save", preserve, preserve_len);
00632           }
00633           buff = bp = alloc_lbuf("did_it.1");
00634           str = d;
00635           mux_exec(buff, &bp, thing, thing, player, EV_EVAL | EV_FIGNORE |EV_TOP, &str, args, nargs);
00636           *bp = '\0';
00637           notify(player, buff);
00638           free_lbuf(buff);
00639        }
00640        free_lbuf(d);
00641     }
00642 
00643 
00644     // Message to neighbors.
00645     //
00646     if (  owhat > 0
00647        && Has_location(player)
00648        && Good_obj(loc = Location(player)))
00649     {
00650         d = atr_pget(thing, owhat, &aowner, &aflags);
00651         if (*d)
00652         {
00653             if (!need_pres)
00654             {
00655                 need_pres = true;
00656                 save_global_regs("did_it_save", preserve, preserve_len);
00657             }
00658             buff = bp = alloc_lbuf("did_it.2");
00659             str = d;
00660             mux_exec(buff, &bp, thing, thing, player, EV_EVAL | EV_FIGNORE | EV_TOP, &str, args, nargs);
00661             *bp = '\0';
00662 
00663             if (*buff)
00664             {
00665                 notify_except2_rlevel2(loc, player, player, thing,
00666                     tprintf("%s %s", Name(player), buff));
00667             }
00668             free_lbuf(buff);
00669         }
00670         else if (odef)
00671         {
00672             notify_except2_rlevel2(loc, player, player, thing,
00673                 tprintf("%s %s", Name(player), odef));
00674         }
00675         free_lbuf(d);
00676     }
00677     else if (  owhat < 0
00678             && odef
00679             && Has_location(player)
00680             && Good_obj(loc = Location(player)))
00681     {
00682         notify_except2_rlevel2(loc, player, player, thing,
00683             tprintf("%s %s", Name(player), odef));
00684     }
00685 
00686     // If we preserved the state of the global registers, restore them.
00687     //
00688     if (need_pres)
00689     {
00690         restore_global_regs("did_it_restore", preserve, preserve_len);
00691     }
00692 
00693     // Do the action attribute.
00694     //
00695     if (  awhat > 0
00696        && IsReal(thing, player))
00697     {
00698         act = atr_pget(thing, awhat, &aowner, &aflags);
00699         if (*act != '\0')
00700         {
00701             charges = atr_pget(thing, A_CHARGES, &aowner, &aflags);
00702             if (*charges)
00703             {
00704                 num = mux_atol(charges);
00705                 if (num > 0)
00706                 {
00707                     buff = alloc_sbuf("did_it.charges");
00708                     mux_ltoa(num-1, buff);
00709                     atr_add_raw(thing, A_CHARGES, buff);
00710                     free_sbuf(buff);
00711                 }
00712                 else
00713                 {
00714                     buff = atr_pget(thing, A_RUNOUT, &aowner, &aflags);
00715                     if (*buff != '\0')
00716                     {
00717                         free_lbuf(act);
00718                         act = buff;
00719                     }
00720                     else
00721                     {
00722                         free_lbuf(act);
00723                         free_lbuf(buff);
00724                         free_lbuf(charges);
00725                         return;
00726                     }
00727                 }
00728             }
00729             free_lbuf(charges);
00730 
00731             CLinearTimeAbsolute lta;
00732             wait_que(thing, player, player, 0, lta, NOTHING, 0, act, args,
00733                  nargs, mudstate.global_regs);
00734         }
00735         free_lbuf(act);
00736     }
00737 }
00738 #endif /* REALITY_LVLS */

Generated on Mon May 28 04:40:10 2007 for MUX by  doxygen 1.4.7