#define MOBILE_C /* Commenting of functions started 8 January 1998 - Marty*/ #include "kernel.h" #include <stdlib.h> #include <unistd.h> #include <strings.h> #include <sys/socket.h> #include "log.h" #include "objsys.h" #include "hate.h" #include "oflags.h" #include "mflags.h" #include "cflags.h" #include "sflags.h" #include "lflags.h" #include "pflags.h" #include "quests.h" #include "sendsys.h" #include "timing.h" #include "mobile.h" #include "communicate.h" #include "jmp.h" #include "rooms.h" #include "parse.h" #include "wizlist.h" #include "bprintf.h" #include "flags.h" #include "wizard.h" #include "misc.h" #include "fight.h" #include "mud.h" #include "commands.h" #include "uaf.h" #include "zones.h" #include "special.h" #include "questpoints.h" #include "quest.h" #include "tables.h" #ifdef GROUP #include "party.h" void setpscore (int pl, int newsc); #endif /***************************************************************************** ** GLOBAL VARIABLES *****************************************************************************/ extern char *WizLevels[]; static void _userlist (char mode); char *make_here (int num); /** XPLEV : returns the real player level of a player, holding into account that ** the player can be assuming a mortal form. ** RETURNS: Player level **/ int xplev(int plr) { if (plr >= max_players) return plev(plr); if (players[plr].defrob != NULL) return players[plr].defrob->real_level; return plev(plr); } #ifdef GROUP /** SETPSCORE: this function replaces the macro in mudmacros.h when the mud ** uses the grouping/party system. It will share all possitive ** points with other members of a group. Negative points are only ** for the player who received them. ** RETURNS : nothing. **/ void setpscore (int pl, int newsc) { if (pl >= max_players) { pscore(pl) = newsc; } else { /* check if the player is in a group to see if points need to be shared or * not */ if (!IN_GROUP(pl)) { pscore(pl) = newsc; } else { /* We need to share points, then lets first see how many points should * be shared by substracting the old score from the new */ int wonsc = newsc-pscore(pl); /* The gained score should be greater than 0, because we only share * won points and not lost points. If we did, it would mean that if * one member dies, he shares the loss with all players, making it * (the dying) easier on him. */ if (wonsc > 0) { int plx; int totalsh = P_GROUP_SHARES(pl) == 0 ? 1 : P_GROUP_SHARES(pl); /* We have the amount of shares in the group, now go through * the whole group and assign the points. */ for (plx = 0; plx < max_players; plx++) { if (is_in_game(plx) && P_GROUP(plx) == P_GROUP(pl)) pscore(plx) += ((P_SHARE(plx) * wonsc)/totalsh); } /* For statistics, add it here as well */ P_GROUP_XP(pl) += wonsc; } else pscore(pl) = newsc; } } } #endif /** CMP_PLAYER: Compare players (for the qsort() function). This is a helper ** function. ** RETURNS : the difference between the two player's levels. **/ int cmp_player (const void *a, const void *b) { return plev (*(int *)b) - plev (*(int *)a); } /***************************************************************************** ** The USERS command. Show names and locations of users. Possibly also ** their local host if PFL_SHUSERS is set. **/ A_COMMAND(usercom) { _userlist (0); } /**************************************************************************** ** The WHO command **/ A_COMMAND(whocom) { _userlist (1); } /***************************************************************************** ** The MLEFT command. Shows the name of all mobiles that are still alive **/ #define COLUMNS (72/MNAME_LEN) /* Calculate the maximum colomns on one row */ A_COMMAND(mleftcom) { char buff[64]; int i; int ct; int zone; int nr; FILE *fp; char fn[512]; Boolean list_all = True; int first = max_players; int last = numchars; zone = 0; /* Check if the player wants to see all mobiles left, or only the mobile's * who are still alive in a particulair zone. */ if (brkword () != -1) { list_all = False; /* Try to find the zone so we can determine where to start and where to * stop. */ if ((zone = get_zone_by_name (wordbuf)) == -1) { bprintf ("No such zone: &+w%s&*\n", wordbuf); return; } first = 0; last = znumchars (zone); } /* Because this output usually covers more than one page we first dump * the results to a file before showing it to the player, so lets open * a temporary file and get to it. */ sprintf(fn,"%smleft.%s",TEMP_DIR,pname(mynum)); if ((fp=fopen(fn,"w"))==NULL) { fwerror(fn); return; } fprintf (fp,"&+wLive Mobiles&*\n&+w%s&*\n",DASHLINE); /* Get all mobiles, starting at the first and ending at the last. If no * zone name was specified, last means the last mobile, otherwise last is * the last mobile of that zone (see above). */ for (ct = first, nr = 0; ct < last; ++ct) { i = list_all ? ct : zmob_nr (ct, zone); /* check if we can see the mobile and if it's alive before adding it * to the list. */ if (!EMPTY (pname (i)) && pstr (i) >= 0 && (pvis (i) <= 0 || pvis (i) <= plev (mynum))) { ++nr; /* Make it show that a mobile in that zone is invisible to * a certain level */ if (pvis (i) > 0) sprintf (buff, "(%s)", pname (i)); else strcpy (buff, pname (i)); fprintf (fp,"%-*s%c", PNAME_LEN + 3, buff, (nr % COLUMNS) ? ' ' : '\n'); } } /* End the file with a statistic and close the file */ fprintf (fp,"\n&+w%s&*\nThere are &+w%d&* mobiles left (from &+w%d&*)\n", DASHLINE, nr, last - first); fclose(fp); /* Open the file pager and show the file paged to the user. After that we * can safely delete the file. */ read_file(fn,NULL,True,NULL); unlink(fn); } /** PLAYER_DAMAGE: returns to total amount of damage a player can inflict, ** taking into account his base damage, plus the damage ** of a possibly wielded weapon. ** RETURNS: the total damage a player can inflict with one hit. **/ int player_damage (int player) { int w; int damage = pdam (player); /* Check if the player is wielding a weapon and if he really has it and has * it wielded. Sometimes this is not the case, so we have to check here. */ if ((w = pwpn (player)) != -1 && iscarrby (w, player) && iswielded (w)) damage += odamage (w); return damage; } /** PLAYER_ARMOR: returns the total amount of armour worn by a player, taking ** into account any armour his body may give him/her. ** RETURNS: Total armour of a player/mobile **/ int player_armor (int player) { int i, j; int armor = parmor (player); /* The armor of the body of the player */ /* run by all objects in his inventory and see which ones his has worn and * if he can really be wearing them. */ for (j = 0; j < pnumobs (player) && (i = pobj_nr (j, player), 1); j++) { if (iswornby (i, player) && otstbit (i, OFL_ARMOR)) armor += oarmor (i); } return armor; } /** USTATS: Shows the statistics for all players. This is the USTATS command. ** It shows a list with details about the players online. It shows ** their name, their level, if they're visible, their damage and ** armour and where they are in the mud. */ void ustats (int minlvl, int maxlvl) { int i, j; int a[256], a_len = 0; char buff[64]; int usercount = 0; /* This is a wizard only command */ if (plev (mynum) < LVL_APPREN) { erreval (); return; } /* run through all players to see which one should appear in the listing. * This means we have to check for players who are logging in, players who * are invisible to the current player and people who are linkdead. * If the outcome is that a player can see a certain player, then it is added * to the list of players to show in this listing. */ for (i = 0; i < max_players; i++) { if ((pvis (i) > plev (mynum) && i != mynum) || #ifdef TCP_ANNOUNCE (!players[i].inp_handler && !players[i].linkdead) || (plev(mynum) < LVL_SENIOR && (!players[i].iamon || players[i].linkdead)) || #else (!players[i].iamon && !players[i].linkdead) || #endif strncasecmp(pname(i), item1, strlen(item1)) || (plev(i) < minlvl) || (plev(i) > maxlvl) ) continue; a[a_len++] = i; } /* Hmm, although there is someone (the current player), the above criteria * caused no players to be found that should show up. So we abort here before * it shows nasty input. */ if (a_len == 0) { bprintf ("No one is online!\n"); return; } /* We prefer our listings sorted by player level. So we sort them using the * default sorting routine: qsort. */ qsort (a, a_len, sizeof (int), cmp_player); /* The header */ bprintf ("&+wLevel Name Status Str/Max Dam Arm Vis" " Idle On For Location\n&+w%s\n&*",MIXLINE); /* Now walk through all players that should be shown and print them to the * player. */ for (j = 0; i = a[j], j < a_len; ++j) { /* linkdead players dont have names. neither have players who are just * logging in, so we have to fake the level here. Als there is a small * trick in there which makes me Creator level no matter what level i am. * For immortals we show the level name, for mortals we show the level. */ if (players[i].linkdead) bprintf("&+w[&+wNoLink &+w]"); else if (!players[i].iamon) { if (!EMPTY(pname(i))) bprintf("&+w[ &+w*tcp* &+w]"); } else if (EQ(pname(i),"Marty")) bprintf ("&+w[&+w%7.7s&+w]","Creator"); else if (plev (i) < LVL_APPREN) bprintf ("&+w[&+w%7d&+w]", plev (i)); else { /* Get the level name for this player */ lev2s(buff,plev(i),psex(i)); bprintf ("&+w[&+w%7.7s&+w]&*", buff); } bprintf (" &+w%-*s", PNAME_LEN, EMPTY(pname(i)) ? "Undecided" : pname(i)); /* It matters only for mortals which level they are. */ if (plev(i) < LVL_APPREN) { if (pfighting(i) >= 0) bprintf ("&+wfgt"); else if (psitting(i)==1) bprintf ("&+wsit"); else if (psitting(i)==2) bprintf ("&+wslp"); else if (psitting(i)==3) bprintf (" &+wtr"); else bprintf (" &+wup"); } else bprintf ("&+w---"); if (plev (i) < LVL_APPREN && players[i].iamon) bprintf (" &+w%3d/&+w%-3d &+w%3d &+w%3d", pstr (i), pmaxstrength (plev (i)), player_damage (i), player_armor (i)); else bprintf (" &+w---/--- &+w--- ---"); bprintf (pvis (i) < LVL_APPREN ? " &+w%3d" : "&+w inv", pvis (i)); if (cur_player->last_cmd >= 0) strcpy (buff, sec_to_hhmmss (time(0) - plast_cmd(i))); else strcpy (buff, sec_to_hhmmss (time(0) + plast_cmd(i))); bprintf ("&+w%9.9s&+w%10.10s &+w%s\n", buff, sec_to_hhmmss (time(0) - plogged_on(i)), (!ploc(i) ? "Unconnected" : showname (ploc (i)))); usercount++; } bprintf ("&+w%s\n&+wA total of &+w%d&+w visible users.&*\n",MIXLINE, (long)usercount); } A_COMMAND(lastoncom) { PERSONA d; Boolean is_mobile; int b; char *name; int laston; int lev; Boolean nofinger=False; char host[MAXHOSTNAMELEN+1]; if (brkword() == -1) { bprintf("Check the last time who was on?\n"); return; } if ((b = fpbns (wordbuf)) != -1 && seeplayer (b)) { is_mobile = b >= max_players; player2pers (&d, NULL, b); laston = 0; name = pname (b); lev = plev(b); nofinger = ststflg(b,SFL_NOFINGER); if (!is_mobile) strcpy(host,players[b].realhostname); } else if (getuaf (wordbuf, &d)) { is_mobile = False; laston = 1; name = d.p_name; lev = d.p_level; nofinger = tst_doublebit(&d.p_sflags,SFL_NOFINGER); strcpy(host,d.p_lasthost); } else { bprintf ("Who's that?\n"); return; } if (is_mobile) bprintf("You can't check when a mobile was last on!\n"); else if (!nofinger || (nofinger && plev(mynum) >= LVL_WIZARD && lev <= plev(mynum))) { if ((lev >= LVL_GOD && plev(mynum) >= LVL_GOD) || lev < LVL_GOD) { bprintf("&+wName\t:&+w %s&*", name); bprintf("\n&+wLast on\t:&+w %s&*", (laston) ? time2ascii(d.p_last_on) : "&+wCurrently Logged on.&*"); bprintf("\n"); } else bprintf("&+wName\t: &+w%s&*\n&+wLast on\t:&+w Unknown.\n",name); if (plev(mynum) >= LVL_ARCHWIZARD) bprintf("&+wlast on from host: &+w%s\n",host); } else bprintf("%s's last on time can't be checked by you.\n",name); } /* The STATS command */ A_COMMAND(showplayer) { extern char *Mflags[]; /* For Behaviour of Mobiles Dump */ char buff[80]; char host[MAXHOSTNAMELEN+1]; PERSONA d; /* If player is not on we need to search the uaf*/ int b; int max_str; int i, j, w=-1, armor; char *title, *name; Boolean in_file, is_mobile; if (!ptstflg (mynum, PFL_STATS)) { erreval (); return; } if (brkword () == -1) { ustats (LVL_MIN, LVL_MAX); return; } /* Get player data */ if ((b = fpbns (wordbuf)) != -1 && seeplayer (b)) { in_file = False; is_mobile = (b >= max_players); player2pers (&d, NULL, b); name = pname (b); title = is_mobile ? NULL : ptitle (b); /*d.p_home = find_loc_by_id (is_mobile ? ploc_reset (b) : phome (b));*/ strcpy(d.p_home, showname (is_mobile ? ploc_reset (b) : phome (b))); max_str = is_mobile ? pstr_reset (b) : maxstrength (b); if (!is_mobile) { if (plev(mynum) < LVL_ARCHWIZARD) strncpy(host,players[b].hostname,MAXHOSTNAMELEN); else strncpy(host,players[b].realhostname,MAXHOSTNAMELEN); } } else if (getuaf (wordbuf, &d)) { in_file = True; is_mobile = False; title = d.p_title; name = d.p_name; max_str = pmaxstrength (d.p_level); if (plev(mynum) >= LVL_ARCHWIZARD) strncpy(host,d.p_lasthost,MAXHOSTNAMELEN); else find_fake_host_name(d.p_name,d.p_lasthost,host); } else { bprintf ("Who's that?\n"); return; } if(d.p_level >= LVL_MAX) { bprintf("Who's that?\n"); return; } if (is_mobile) { if (!can_manipulate(mynum,b) ) { bprintf("You can't see %s %s status, %s is out of your reach.\n", d.p_name, his_or_her(b), psex(b) ? "she" : "he"); return; } } bprintf ("&+w[&+w%-13s&+w]&+w=============================================================",name ); if (!is_mobile) { bprintf ("\n&+wTitle &+w:&* %s", make_title (title, "<name>")); bprintf ("\n&+wEmail &+w:&+w %s", (tst_doublebit(&d.p_sflags,SFL_NOFINGER)) ? "Private" : d.p_email); bprintf ("\n&+wScore &+w:&* %-7d &+wLevel &+w:&* %d", d.p_score,d.p_level); bprintf ("\n&+wQuestpoints&+w:&* %-2d",d.p_questpoints); } bprintf ("\n&+wStrength &+w: &+w%d&+w/%d" "\n&+wDamage &+w:&* %d", d.p_strength, max_str, d.p_damage); if (!in_file && (w = pwpn (b)) != -1 && iscarrby (w, b) && iswielded (w)) { int w_damage = is_mobile ? odamage (w) / 2 : odamage (w); bprintf (" + %s(%d) = %d", oname (w), w_damage, w_damage + d.p_damage); } bprintf ("\n&+wArmor &+w:&* %d", armor = d.p_armor); if (!in_file) { for (j = 0; j < pnumobs (b) && (i = pobj_nr (j, b), 1); j++) { if (iswornby (i, b) && otstbit (i, OFL_ARMOR)) { armor += oarmor (i); bprintf (" + %s(%d)", oname (i), oarmor (i)); } } if (armor != d.p_armor) bprintf (" = %d", armor); } bprintf ("\n&+wVisibility &+w:&* %d ", d.p_vlevel); if (is_mobile) { bprintf ("\n&+wAggression &+w:&* %-3d %% &+wSpeed &+w:&* %d", pagg (b),pspeed(b)); bprintf ("\n&+wHates &+w:&* %s",((i = hates_who(b)) == -1) ? "No one" : pname(i)); bprintf ("\n&+w%s &+w:&* %s", zpermanent (pzone (b)) ? "Zone " : "Owner", zname (pzone (b))); } bprintf("\n&+wWimpy &+w:&* %2d &+wDied&+w: &*%3d &+wTourny kills&+w :&* %3d",d.p_wimpy, d.p_died, d.p_killed); if (exists (findroomnum(d.p_home))) bprintf ("\n&+wStart &+w:&* %s \t(%s)", sdesc (findroomnum(d.p_home)), d.p_home /*xshowname (buff, d.p_home)*/); if (!in_file) { bprintf ("\n&+wLocation &+w:&* %s \t(%s)", sdesc (ploc (b)), xshowname (buff, ploc (b))); bprintf ("\n&+wCondition &+w:&*"); if (pfighting (b) >= 0) bprintf (" Fighting %s", pname (pfighting (b))); if (phelping (b) >= 0) bprintf (" Helping %s", pname (phelping (b))); if (psitting (b) == 1) bprintf (" Sitting"); if (psitting (b) == 2) bprintf (" Sleeping"); if (psitting (b) == 3) bprintf (" In trance"); if (is_mobile) { bprintf ("\n&+wBehavior &+w:&*\n"); show_bits ((int *) &mflags (b), sizeof (MFLAGS) / sizeof (int), Mflags); } } else if ((d.p_level >= LVL_GOD && plev(mynum) >= LVL_GOD) || d.p_level < LVL_GOD) { bprintf ("\n&+wLast on &+w:&* %s", time2ascii (d.p_last_on)); } if (ptstflg (mynum, PFL_SHUSER) && !is_mobile) { bprintf ("\n&+w%s &+w:&* %s", in_file ? "Last Host" : "From Host",host); } #ifdef ARENA if (!is_mobile) { bprintf("\n&+wArena wins &+w: %d &+wlosses&+w: %d", combatwins(b),combatlosses(b)); } #endif if (d.p_sflags.b3 != 0 || d.p_sflags.b2 != 0 || d.p_sflags.b1 != 0) { if (!is_mobile) bprintf ("\n"); bprintf ("&+wVarious &+w:&*\n"); show_bits ((int *) &(d.p_sflags), sizeof (SFLAGS) / sizeof (int), Sflags); } else bprintf("\n"); bprintf ("&+w%s\n",DASHLINE); } /* The MOBILE command */ A_COMMAND(mobilecom) { FILE *fp; char fn[512]; int i; int ct; int zone; int live = 0; int dead = 0; Boolean list_all = True; int first = max_players; int last = numchars; zone = 0; if (plev (mynum) < LVL_APPREN) { erreval (); return; } if (brkword () != -1) { list_all = False; if ((zone = get_zone_by_name (wordbuf)) == -1) { bprintf ("No such zone: %s\n", wordbuf); return; } first = 0; last = znumchars (zone); } sprintf(fn,"%smobile.%s",TEMP_DIR,pname(mynum)); if ((fp = fopen(fn,"w"))==NULL) { fwerror(fn); return; } fprintf (fp,"&+wMobiles&*\n&+w%s&*\n",MIXLINE); if (the_world->w_mob_stop) fprintf (fp," [Currently STOPped]"); for (ct = first; ct < last; ++ct) { i = list_all ? ct : zmob_nr (ct, zone); fprintf (fp,"%4d %-*s %c", i + GLOBAL_MAX_OBJS, MNAME_LEN, EMPTY (pname (i)) ? pname_reset (i) : pname (i), ststflg (i, SFL_OCCUPIED) ? '*' : ' '); if (EMPTY (pname (i))) { fprintf (fp,"<QUIT or KICKED OFF>\n"); ++dead; } else { fprintf (fp,"%s\n",xdesrm (globalbuf,ploc (i), IN_ROOM)); if (pstr (i) < 0) ++dead; else ++live; } } fprintf (fp,"&+w%s&*\nA total of %d live mobile(s) + %d dead = %d.\n", MIXLINE,live, dead, live + dead); fclose(fp); read_file(fn,NULL,True,NULL); /* Paged dump */ unlink(fn); } /* List the people in a room as seen from myself */ void list_people (void) { int i, j; int room = ploc (mynum); for (j = 0; j < lnumchars (room) && (i = lmob_nr (j, room), 1); j++) { if (i != mynum && is_in_game (i) && seeplayer (i)) { /* mobile ? */ if (i >= max_players) { bprintf ("%s%s%s\n", pvis (i) > 0 ? "(" : "", pftxt (i), pvis (i) > 0 ? ")" : ""); } else if (players[i].linkdead == True) { bprintf("A stone statue of %s stands here. &+w(&+wlinkdead&+w)&*\n", pname(i)); } else /* Player ? */ { bprintf ("%s%s%s\n", pvis (i) > 0 ? "(" : "", make_here (i), pvis (i) > 0 ? ")" : ""); } if (gotanything (i) && !ststflg(mynum, SFL_NOINVEN)) print_inventory(i); } } } Boolean eat_out_of_fleeing(int plx, int_set *inventory) { int ob; Boolean yesno = False; int_set *inv; if (ststflg(plx,SFL_AUTOEAT)) { if (inventory == NULL) inv = pinv(plx); else inv = inventory; for (ob = first_obj(inv); ob != SET_END; ob = next_obj(inv)) { if (iscarrby(ob,plx) && (otstbit(ob,OFL_FOOD) || otstbit(ob,OFL_BOOZE))) { eat(ob); if (!yesno) { sendf(plx,"You frantically search your inventory for any food and munch away.\n"); send_msg(ploc(plx),0,pvis(plx),LVL_MAX,plx,NOBODY, "%s quickly eats some food to restore %s strength.\n", pname(plx),his_or_her(plx)); yesno = True; } send_msg(ploc(plx),MODE_NOBLIND,pvis(plx),LVL_MAX, plx, NOBODY, "%s greedily devours the %s.\n", pname(mynum), oname(ob)); sendf(plx,"You quickly eat the %s.\n",oname(ob)); eat(ob); setpstr(plx,pstr(plx) + 12); } else if (otstbit(ob,OFL_CONTAINER)) { yesno = (yesno || eat_out_of_fleeing(plx,oinv(ob))); } if (pstr(plx) >= maxstrength(plx)) return yesno; } } if (!yesno && inventory == NULL) sendf(plx,"You frantically search your inventory for something to eat but find nothing.\n"); return yesno; } void fleemob(int plx) { static char *fleemsg[] = { "%s says &+w'Yikes, I'm outta here.'&*\n", "%s makes a frantic attempt to flee.\n", "%s says &+w'It was nice talking to you, but I got to go.'&*\n", "%s ducks the attack and heads for one of the exits.\n", "%s says &+w'See ya!'\n" }; if (!mtstflg(plx,MFL_NOTALK)) sendf(ploc(plx),fleemsg[MY_RANDOM() % ARRAYSIZE(fleemsg)],pname(plx)); movemob(plx); } /***************************************************************************** ** All in one function that can replace move_mobiles() and onlook(), uses ** one for loop instead of four. ****************************************************************************/ void do_move_fight(void) { register int plx, vict; for (plx = 0; plx < numchars; plx++) { if (!is_in_game(plx)) continue; /* Do mobile stuff */ if (plx >= max_players) { if (!ststflg(plx,SFL_OCCUPIED) && alive(plx) != -1) { consid_move(plx); chkfight(plx); } } else /* Do player stuff */ { if (phelping (plx) != -1) helpchkr (plx); } /* Combat control */ if ((vict = pfighting(plx)) >= 0) { /* One of the players fled from the scene */ if (ploc(vict) != ploc(plx) || testpeace(plx)) pfighting(plx) = pfighting(vict) = -1; else { hit_player(plx,vict,pwpn(plx)); /** "Wimpy" code, make victim flee if his ** strength is less then his "wimpy" val. ** Mobile wimpy by Marty 1996 **/ if (pstr (vict) >= 0 && pstr (vict) < pwimpy (vict)) { if (eat_out_of_fleeing(vict,NULL)) continue; if (vict < max_players) /* Player flee */ { int x = mynum; setup_globals (vict); stp = 0; strbuf[0] = '\0'; fleecom(); setup_globals (x); } else { fleemob(vict); } } } } } if (ocarrf (RuneSword_Obj) >= CARRIED_BY) { dorune (oloc (RuneSword_Obj)); } } void consid_move (int mon) { static char *underwater[] = { "&+wBlub blub blub&*", "&+wGorglll blub blub&*", "&+wprrrrrrrrr blub blub&*" }; static char *weak[] = { "&+wOuch! That hurts!&*", "&+wI'm telling my mommy!&*", "&+wOw!&*", "&+wLeave me alone!&*" }; static char *medium[] = { "&+wHmm... I'm not so sure about this...", "&+wWow, you're good.", "&+wWhew, I need a break!", "&+wThis sucks." }; static char *strong[] = { "&+wPuny mortal!&*", "&+wYou cannot defeat me!&*", "&+wYou shall die!&*", "&+wFlee, while you still can, weakling!&*", "&+wGee, you're funny!&*" }; int plx, s, t; if (EMPTY (pname (mon))) return; for (plx = 0; plx < lnumchars (ploc (mon)); plx++) { if (pfighting(lmob_nr(plx, ploc(mon)) ) == mon && !mtstflg(mon,MFL_NOTALK) ) { if(randperc() > 8) return; /* Don't talk underwater */ if (!ltstflg(ploc(mon),LFL_IN_WATER) ) { s = pstr_reset(mon) - pstr(mon); t = (int) (pstr_reset(mon) / 3); if(s < (2 * t)) { sendf(ploc(mon), "&+w\001p%s\003&* says '&+w%s&*'\n", pname(mon), strong[MY_RANDOM() % ARRAYSIZE(strong)]); return; } else if(s < t) { sendf(ploc(mon), "&+w\001p%s\003&* says '&+w%s&*'\n", pname(mon), medium[MY_RANDOM() % ARRAYSIZE(medium)]); return; } else sendf(ploc(mon), "&+w\001p%s\003&* says '&+w%s&*'\n", pname(mon), weak[MY_RANDOM() % ARRAYSIZE(weak)]); } else /* Unless it is mixed with air bubbles */ sendf(ploc(mon),"&+w\001p%s\003&* says '&+w%s&*'\n", pname(mon) , underwater[MY_RANDOM() % ARRAYSIZE(underwater)]); } } if (pspeed(mon) > 0 && pfighting(mon) < 0) if (randperc () * 6 / (10 * TIMER_INTERRUPT) < pspeed (mon)) movemob (mon); if (((mtstflg (mon, MFL_THIEF) && randperc () < 20 && stealstuff (mon))) || ((mtstflg (mon, MFL_PICK) && randperc () < 40 && shiftstuff (mon)))) return; } /* Handle Runesword */ void dorune (int plx) { int ply; if (pfighting (plx) >= 0 || testpeace (plx)) return; for (ply = lfirst_mob (ploc (plx)); ply != SET_END; ply = lnext_mob (ploc (plx))) { if (ply != plx && !EMPTY (pname (ply)) && plev (ply) < LVL_APPREN && fpbns (pname (ply)) >= 0 && randperc () >= 9 * plev (plx)) { sendf (plx, "The Runesword twists in your hands, lashing out savagely!\n"); hit_player (plx, ply, RuneSword_Obj); return; } } } Boolean dragget (void) { int l,i; if (plev (mynum) >= LVL_APPREN) return False; for (i=0; dragget_mobs[i] != -1; i++) { l = dragget_mobs[i]+max_players; if (alive(l) != -1 && ploc(l) == ploc(mynum)) { bprintf("%s",dragget_msgs[i]); return True; } } return False; } void helpchkr (int plx) { int x = phelping (plx); if (!is_in_game (x)) { sendf (plx, "You can no longer help.\n"); setphelping (plx, -1); } else if (ploc (x) != ploc (plx)) { sendf (plx, "You can no longer help %s.\n", pname (x)); sendf (x, "%s can no longer help you.\n", pname (plx)); setphelping (plx, -1); } } void movemob (int x) { int n, r; if (the_world->w_mob_stop) return; r = randperc () % NEXITS; /* change this.... here chance is less if few exits */ if ((n = getexit (ploc (x), r)) >= EX_SPECIAL) return; if (n >= DOOR) { if (state (n - DOOR) > 0) return; n = obj_loc (olinked (n - DOOR)); } if (n >= 0 || ltstflg (n, LFL_NO_MOBILES) || ltstflg (n, LFL_DEATH)) return; send_msg (ploc (x), 0, pvis (x), LVL_MAX, x, NOBODY, "%s has gone %s.\n", pname (x), exits[r]); setploc (x, n); send_msg (ploc (x), 0, pvis (x), LVL_MAX, x, NOBODY, "%s has arrived.\n", pname(x)); } /* * Steal random object from random player in the same room * -Nicknack Sep. 1990 * improved by Alf Oct, 1991 * improved by Nicknack May, 1993 */ Boolean stealstuff (int m) { int p[50]; /* Room for mortals and objects */ int i, j, k; int nr = 0; /* Count the number of mortals in the same room: */ for (j = 0; j < lnumchars (ploc (m)) && nr < 50; j++) { i = lmob_nr (j, ploc (m)); if (is_in_game (i) && i < max_players && plev (i) < LVL_APPREN) { p[nr++] = i; } } if (nr == 0) return False; /* select a random one of those in the same room: */ i = p[randperc () % nr]; /* Count the number of objects he carries that we can take: */ for (nr = k = 0; k < pnumobs (i) && nr < 50; k++) { j = pobj_nr (k, i); if (iscarrby (j, i)) { if (((ocarrf (j) == WORN_BY || ocarrf (j) == BOTH_BY) && !mtstflg (m, MFL_SWORN)) || ((ocarrf (j) == WIELDED_BY || ocarrf (j) == BOTH_BY) && !mtstflg (m, MFL_SWPN))) continue; else p[nr++] = j; } } if (nr == 0) return False; /* Select random object from those he carries */ j = p[randperc () % nr]; sendf (i, "\001p%s\003 steals the %s from you!\n", pname (m), oname (j)); send_msg (ploc (i), 0, LVL_MIN, LVL_MAX, i, NOBODY, "\001p%s\003 steals the %s from \001p%s\003!\n", pname (m), oname (j), pname (i)); if (otstbit (j, OFL_WEARABLE)) { setoloc (j, m, WORN_BY); } else { setoloc (j, m, CARRIED_BY); } if (otstbit (j, OFL_WEAPON) && (pwpn (m) == -1 || odamage (pwpn (m)) < odamage (j))) { set_weapon (m, j); } return True; } Boolean shiftstuff (int m) { Boolean took = False; int a, b; int maxdam = 0, w = -1; int maxarm = 0, ww = -1; if (pwpn(m) != -1) { w = pwpn(m); maxdam = odamage(w); } for (b = 0; b < lnumobs (ploc (m)); b++) { a = lobj_nr (b, ploc (m)); if (!oflannel (a) && !otstbit(a,OFL_NOMGET)) { took = True; sendf (ploc (m), "\001p%s\003 takes the %s.\n", pname (m), oname (a)); /* Wield the best weapon, wear the best armor: */ if (otstbit (a, OFL_WEAPON) && odamage (a) > maxdam) { w = a; maxdam = odamage (a); } if (otstbit (a, OFL_ARMOR) && oarmor (a) > maxarm) { ww = a; maxarm = oarmor (a); } setoloc (a, m, CARRIED_BY); } if (w >= 0) set_weapon (m, w); if (ww >= 0) { setoloc (ww, m, (w == ww) ? BOTH_BY : WORN_BY); } } return took; } char * xname (char *n) { char *t; if (n != NULL && (t = strrchr (n, ' ')) != NULL) { return t + 1; } return n; } void setname (int plx) { register PLAYER_REC *p = cur_player; if (psex (plx)) p->wd_them = strcpy (p->wd_her, pname (plx)); else p->wd_them = strcpy (p->wd_him, pname (plx)); } Boolean see_player (int pla, int plb) { if (pla < 0 || pla >= numchars) return False; if (plb == pla || plb < 0 || plb >= numchars) return True; if (pvis (plb) > 0 && plev (pla) < pvis (plb)) return False; if (ststflg (pla, SFL_BLIND)) return False; if (ploc (pla) == ploc (plb) && r_isdark (ploc (pla), pla)) return False; return True; } char * see_name (int pla, int plb) { return see_player (pla, plb) ? pname (plb) : "Someone"; } Boolean seeplayer (int plx) { if (plx == mynum || plx < 0 || plx >= numchars) return True; if (!see_player (mynum, plx)) return False; setname (plx); return True; } /* Return a player index given a target name on one of the forms: * 1) <player-number> * 2) <player-name> * 3) <player-name><number-in-sequence-with-that-name> * * Return -1 if not found. */ int find_player_by_name (char *name) { char b[MNAME_LEN + 1], *p = b; int n, i; int nn; if (name == NULL || strlen (name) > MNAME_LEN) return -1; name = xname (name); /* Skip the "The " if there. */ while (*name != '\0' && isalpha (*name)) *p++ = *name++; *p = '\0'; if (isdigit (*name)) { n = atoi (name); while (isdigit (*++name)); if (*name != '\0') return -1; } else if (*name != '\0') { return -1; } else n = 1; if (*b == '\0') { if (n >= GLOBAL_MAX_OBJS && n < GLOBAL_MAX_OBJS + numchars && is_in_game (n - GLOBAL_MAX_OBJS)) return n - GLOBAL_MAX_OBJS; else return -1; } else { /* Try the mobiles in the players location first: */ if (is_in_game (mynum)) { int m = n; int loc = ploc (mynum); for (i = 0; i < lnumchars (loc); i++) { if (EQ (b, xname (pname (lmob_nr (i, loc)))) && is_in_game (lmob_nr (i, loc)) && --m == 0) return lmob_nr (i, loc); } if (m < n) return -1; } /* Now try anyone. */ nn = n; /* got an exact match? */ for (i = 0; i < numchars; i++) { if (EQ (b, xname (pname (i))) && is_in_game (i) && --n == 0) return i; } n = nn; if (cur_player) if (cur_player->iamon) for (i = 0; i < numchars; i++) { if (!strncasecmp (b, xname (pname (i)), strlen (b)) && is_in_game (i) && --n == 0) return i; } } return -1; } /* Find player by name, if visible to mynum: */ int fpbn (char *name) { int n = find_player_by_name (name); return n < 0 || seeplayer (n) ? n : -1; } /* Find mobile's in-game index from its ID. Return -1 if not found. */ int find_mobile_by_id (long int id) { long int x; if (id >= max_players && id < num_const_chars) return id; return (x = lookup_entry (id, &id_table)) == NOT_IN_TABLE || x < 0 || x >= numchars ? -1 : x; } /* Find player or mobile, return number if in game. * Set f to true if in file, False if in game. If exists, put * the data in the object pointed to by p. */ int find_player (char *name, PERSONA * p, Boolean * f) { int plr; *f = False; if ((plr = fpbns (name)) >= 0) { if (!seeplayer (plr)) return -1; player2pers (p, NULL, plr); return plr; } else if (ptstflg (mynum, PFL_UAF) != 0 && getuaf (name, p)) { *f = True; return -2; } return -1; } int alive (int i) { if ((pstr(i) < 0) || (EMPTY (pname (i))) || (EQ(pname(i),"Corpse"))) return -1; else return i; } int wlevel (int lev) { if (lev < LVL_GUEST) return LEV_NEG; /* Negative level */ if (lev < LVL_APPREN) return LEV_MORTAL; /* Mortal */ if (lev == LVL_APPREN) return LEV_APPRENTICE; /* Apprentice */ if (lev < LVL_WIZARD) return LEV_EMERITUS; /* Emeriti */ if (lev < LVL_SENIOR) return LEV_WIZARD; /* Wizard */ if (lev < LVL_COUNSEL) return LEV_SENIOR; if (lev < LVL_ARCHWIZARD) return LEV_COUNSEL; /* Senior */ if (lev < LVL_HIGHARCH) return LEV_ARCHWIZARD; /* Arch wizard */ if (lev < LVL_ADVISOR) return LEV_HIGHARCH; if (lev < LVL_DEMI) return LEV_ADVISOR; /* High Arch */ if (lev < LVL_HIGHDEMI) return LEV_DEMI; /* Demi */ if (lev < LVL_GOD) return LEV_HIGHDEMI; /* High Demi */ if (lev < LVL_MASTER) return LEV_GOD; /* God */ return LEV_MASTER; /* Master */ } Boolean do_okay_l (int p, int v, Boolean c) { int lev_p = wlevel (p); int lev_v = wlevel (v); if (lev_v > lev_p && lev_p > LEV_NEG) { return False; } return (c || (lev_v < lev_p && lev_p > LEV_WIZARD) || lev_p >= LEV_MASTER); } /* Can p(layer) do XX to v(ictim) ? * ** prot_flag protects against it. */ Boolean do_okay (int p, int v, int prot_flag) { return do_okay_l (xplev (p), xplev (v), (prot_flag < PFL_MAX && !ptstflg (v, prot_flag))); } void setpsex (int chr, Boolean v) { if (v) ssetflg (chr, SFL_FEMALE); else sclrflg (chr, SFL_FEMALE); } /* SET Player LOCation. */ void setploc (int plr, int room) { /* First remove plr from his current location: */ if (exists (ploc (plr))) remove_int (plr, lmobs (ploc (plr))); /* Then add him to the new room: */ if (exists (room)) add_int (plr, lmobs (room)); ploc (plr) = room; } int ptothlp (int pl) { int ct; for (ct = 0; ct < numchars; ct++) { if (ploc (ct) == ploc (pl) && phelping (ct) == pl) return ct; } return -1; } int maxstrength (int p) { return pmaxstrength (plev (p)); } char * make_here (int num) { static char buff[256]; static char tbuff[512]; register int t; /* int save_mynum;*/ if (num >= max_players) { /* mobile */ sprintf (buff, "%s", pftxt (num)); } else { /* save_mynum = real_mynum; setup_globals (num); *//* all nums were mynums */ if (!psitting(num)) { build_setin(num,buff,players[num].setstand, pname(num), NULL); /*build_setin(num,buff,cur_player->setstand, pname(num), NULL);*/ sprintf(tbuff,"%s",buff); } else if (psitting(num)==1) { build_setin(num,buff,players[num].setsit, pname(num), NULL); /* build_setin(num,buff,cur_player->setsit, pname(num), NULL);*/ sprintf(tbuff,"%s",buff); } else if (psitting(num)==2) { build_setin(num,buff,players[num].setsleep, pname(num), NULL); /*build_setin(num,buff,cur_player->setsleep, pname(num), NULL);*/ sprintf(tbuff,"%s",buff); } else if (psitting(num)==3) { build_setin(num,buff,players[num].settrance , pname(num), NULL); /*build_setin(num,buff,cur_player->settrance , pname(num), NULL);*/ sprintf(tbuff,"%s",buff); } if (ststflg(num, SFL_GLOWING)) strcat(tbuff," (providing light)"); for (t = 0; t != PNAME_LEN + TITLE_LEN + 20; t++) if (tbuff[t] == '%' && tbuff[t + 1] == 'n') { tbuff[t] = '%'; tbuff[t + 1] = 's'; } sprintf (buff, tbuff, pname (num)); /* setup_globals (save_mynum); */ } return buff; } char * make_title (char *title, char *name) { static char buff[PNAME_LEN + TITLE_LEN + 20]; sprintf (buff, (EMPTY (title) ? "%s the Unknown" : title), name); return buff; } char * std_title (int level, Boolean sex) { extern char *MLevels[]; extern char *FLevels[]; extern char *FWizLevels[]; extern char *WizLevels[]; static char buff[TITLE_LEN + 10]; int wl = wlevel (level); strcpy (buff, "%s the "); switch (wl) { case LEV_NEG: strcat (buff, "Mobile"); break; case LEV_MORTAL: case LEV_APPRENTICE: strcat (buff, (sex ? FLevels : MLevels)[level]); break; default: strcat (buff, sex ? FWizLevels[wl] : WizLevels[wl]); } return buff; } /* Try to reset a mobile. */ Boolean reset_mobile (int m) { int loc; setpstr (m, pstr_reset (m)); setpvis (m, pvis_reset (m)); setpflags (m, pflags_reset (m)); setmflags (m, mflags_reset (m)); setsflags (m, sflags_reset (m)); setpmsk1 (m, 0); setpmsk2 (m, 0); setpmsk3 (m, 0); setpsitting (m, 0); setpfighting (m, -1); setphelping (m, -1); setpwpn (m, -1); setplev (m, plev_reset (m)); setpagg (m, pagg_reset (m)); setpspeed (m, pspeed_reset (m)); setpdam (m, pdam_reset (m)); setparmor (m, parmor_reset (m)); setpwimpy (m, pwimpy_reset (m)); clear_hate(m); if (EMPTY (pname (m))) setpname (m, pname_reset (m)); if ((loc = find_loc_by_id (ploc_reset (m))) == 0) { setpstr (m, -1); setploc (m, dead_loc); return False; } else { setploc (m, loc); return True; } } void p_crapup (int player, char *str, int flags) { int m = real_mynum; if (pfighting(player) > 0) { m = pfighting(player); setpfighting(player,-1); setpfighting(m,-1); m = real_mynum; } setup_globals (player); if (player > max_players && player < numchars) crapup(str, flags | CRAP_UNALIAS | CRAP_RETURN); else crapup (str, flags | CRAP_RETURN ); setup_globals (m); } void crapup (char *str, int flags) { if ((flags & CRAP_UNALIAS) != 0) { if (pfighting(mynum) >= 0) setpfighting(mynum,-1); unalias (real_mynum); unpolymorph (real_mynum); return; } xcrapup (str, (flags & CRAP_SAVE) != 0); if ((flags & CRAP_RETURN) == 0) { longjmp (to_main_loop, JMP_QUITTING); } } void xcrapup (char *str, Boolean save_flag) { int i,temp; if (cur_player->aliased) { bprintf ("%s\n", str); unalias (real_mynum); return; } else if (cur_player->polymorphed >= 0) { bprintf ("%s\n", str); unpolymorph (real_mynum); return; } if (mob_fun(real_mynum) != NULL && !players[real_mynum].linkdead) { param_s.plx = real_mynum; mob_fun(real_mynum)(E_STORE); } #ifdef GROUP if (IN_GROUP(real_mynum)) { int plx=mynum; setup_globals(real_mynum); pleave(); setup_globals(plx); } #endif temp = real_mynum; clear_mobs_hate(mynum); for(i=0;i<max_players;i++) { if (players[i].converse.active == True) if (players[i].converse.talking_to == temp) { sendf(i,"%s has left, you can no longer converse with them.\n", pname(temp)); players[i].converse.talking_to = -1; players[i].converse.active = False; strcpy(players[i].prompt, players[i].converse.old_prompt); } if (players[i].i_follow == temp) { sendf(i,"%s died, you can't follow %s anymore.\n", pname(temp), him_or_her(temp)); players[i].i_follow = -1; } } setup_globals(temp); if (cur_player->defrob != NULL) { setplev(mynum,cur_player->defrob->real_level); pflags(mynum).b1 = cur_player->defrob->real_pflags.b1; pflags(mynum).b2 = cur_player->defrob->real_pflags.b2; pflags(mynum).b3 = cur_player->defrob->real_pflags.b3; pmask(mynum).b1 = cur_player->defrob->real_mask.b1; pmask(mynum).b2 = cur_player->defrob->real_mask.b2; pmask(mynum).b3 = cur_player->defrob->real_mask.b3; setpdam(mynum,cur_player->defrob->real_dam); setparmor(mynum,cur_player->defrob->real_armor); setpstr(mynum,pmaxstrength(plev(mynum))); setpvis(mynum,cur_player->defrob->real_vis); free(cur_player->defrob); cur_player->defrob = NULL; } if (cur_player->editor.active == True) { Line *s, *p; p = cur_player->editor.start; while (p != NULL) { s = p->next; free(p->line); free(p); p = s; } cur_player->editor.active = False; cur_player->editor.current = NULL; strcpy(cur_player->prompt,cur_player->editor.old_prompt); } loseme (save_flag); if (str != NULL) { bprintf ("\n%s\n\n%s\n\n%s\n", DASHLINE, str, DASHLINE); bflush (); } remove_entry (mob_id (mynum), &id_table); shutdown(cur_player->fil_des,0); cur_player->iamon = False; setpname (mynum, ""); setploc (mynum, 0); quit_player (); /* So we don't get a prompt after exit */ } /* Remove me from the game. Dump objects, send messages, save etc.. * May only be used after has been called. */ void loseme (Boolean save_flag) { char b[80]; int x, y ; Boolean emp = EMPTY (pname (mynum)); if (cur_player->aliased || cur_player->polymorphed >= 0) return; if (cur_player->iamon) { if (!emp) { if (save_flag) save_player(mynum,True); if ((x = the_world->w_lock) > 0 && (y = plev (mynum)) >= x && y >= LVL_APPREN) bprintf ("\nDon't forget the game is locked....\n"); send_msg (DEST_ALL, MODE_BRACKET|MODE_QUIET, Max(pvis (mynum), LVL_APPREN), LVL_MAX, mynum, NOBODY, "%s has departed from MUD in %s &+w(%s)", pname (mynum), sdesc (ploc (mynum)), xshowname (b, ploc (mynum))); } dumpitems (); if (!emp) { if (plev(mynum) < LVL_APPREN) mudlog ("CONN: Exit %s [lev %d, scr %d, str %d/%d][fd: %d]", pname(mynum), plev (mynum), pscore (mynum),pstr(mynum), maxstrength(mynum),cur_player->fil_des); else if (pvis(mynum) < (LVL_GOD+1)) mudlog ("CONN: Exit %s [lev %d][fd: %d]",pname(mynum),plev(mynum),cur_player->fil_des); setpname (mynum, ""); setploc (mynum, 0); } cur_player->iamon = False; snoop_off (mynum); } } char * lev2s (char *b, int lvl, Boolean x) { extern char *FLevels[]; extern char *MLevels[]; extern char *FWizLevels[]; extern char *WizLevels[]; if (lvl <= LVL_APPRENTICE) { if (x) strcpy(b,FLevels[lvl]); else strcpy(b,MLevels[lvl]); } else if (lvl > LVL_APPREN && lvl < LVL_MAX) { int wlev = wlevel(lvl); if (x) strcpy(b,FWizLevels[wlev]); else strcpy(b,WizLevels[wlev]); } else sprintf(b,"Level %d",lvl); strcat(b," "); return b; } int tscale (void) { int a = 0; int b; for (b = 0; b < max_players; b++) if (is_in_game (b) && plev (b) < LVL_APPREN) a++; if (a < 2) return 1; else return (a > 9 ? 9 : a); } Boolean chkdumb (void) { if (!ststflg (mynum, SFL_DUMB)) return False; bprintf ("You are mute.\n"); return True; } Boolean chkcrip (void) { if (!ststflg (mynum, SFL_CRIPPLED)) return False; bprintf ("You are crippled.\n"); return True; } Boolean chksitting (void) { if (!psitting (mynum)) return False; bprintf ("You'll have to stand up, first.\n"); return True; } void calib_player (int pl) { extern char *MLevels[]; extern char *FLevels[]; int b = 1,qp; int oldlevel; if (pl >= max_players || !players[pl].iamon || players[pl].aliased || players[pl].polymorphed >= 0) return; if (pl < max_players && wlevel(xplev(pl)) == LEV_WIZARD && q_all(&qflags(pl))) { char *levstr = ""; extern char *FWizLevels[]; extern char *WizLevels[]; if (players[pl].defrob != NULL) { players[pl].defrob->real_level = LVL_SENIOR; set_xpflags(players[pl].defrob->real_level, &(players[pl].defrob->real_pflags), &(players[pl].defrob->real_mask) ); } else { setplev(pl,LVL_SENIOR); setptitle(pl, std_title(b, psex(pl))); set_xpflags(plev(pl), &pflags(pl), &pmask(pl) ); } update_wizlist(pname(pl), wlevel(plev(pl))); levstr = psex(pl) ? FWizLevels[wlevel(xplev(pl))] : WizLevels[wlevel(xplev(pl))]; mudlog("GAME: %s has qualified for %s",pname(pl),levstr); sendf(pl,"&+wCongratulations, you qualified for %s!&*\n", levstr); send_msg(DEST_ALL,MODE_QUIET|MODE_BRACKET,LVL_APPREN,LVL_MAX,pl,NOBODY, "%s is now %s!",pname(pl),levstr); } else if (plev(pl) >= LVL_APPREN) return; oldlevel = plev(pl); b = levelof(pscore(pl), plev(pl) ); qp = qp_for_level(b); if (b == LVL_APPREN && oldlevel < LVL_SIXTEEN) b = LVL_SIXTEEN; if (qpoints(pl) < qp) { Boolean go_on = False; for (b -= 1;b > plev(pl); b--) { qp = qp_for_level(b); if (qpoints(pl) >= qp) go_on = True; } if (!go_on) return; } if (b == LVL_APPREN && !q_required(&qflags(pl))) return; if (b == LVL_APPREN && players[pl].defrob != NULL) return; if (b != oldlevel && oldlevel > 0) { setplev(pl, b); setptitle(pl, std_title(b, psex(pl))); mudlog("%s went from level %d to level %d.",pname(pl),oldlevel,b); if (b > oldlevel) { sendf(pl,"&+wCongratulations, %s!&*\n", make_title(ptitle(pl), pname(pl)) ); } else sendf(pl,"You are now %s\n", make_title( ptitle(pl), pname(pl))); send_msg(DEST_ALL,MODE_QUIET|MODE_BRACKET,LVL_APPREN,LVL_MAX,pl,NOBODY, "%s went from level %d to %d",pname(pl),oldlevel,b ); /*saveallcom();i*/ /* I dont think a saveall is needed */ save_player(pl,True); setpstr(pl, maxstrength(pl)); if (b > oldlevel) switch (b) { case LVL_FOUR: set_doublebit(&pflags(pl), PFL_EMOTE); set_doublebit(&pflags(pl), PFL_TITLES); sendf(pl,"You may now emote and change your own title.\n"); break; case LVL_SEVEN: sendf(pl,"Welcome %s, you may now use the POSE command.\n", (psex(pl) ? FLevels : MLevels)[LVL_SEVEN]); break; case LVL_EIGHT: sendf(pl,"You can now use the SCAN command to probe adjacent rooms.\n"); break; case LVL_TEN: sendf(pl,"Nice work, %s. You may now use the BANG command.\n", (psex(pl) ? "Dudette" : "Dude") ); break; case LVL_TWELVE: set_doublebit(&pflags(pl), PFL_CANTRANCE); sendf(pl,"You are now trained enough to use the trance as a form of heal.\n"); break; case LVL_FIFTEEN: set_xpflags(LVL_FIFTEEN, &pflags(pl) , &pmask(pl) ); sendf(pl,"My complements %s! You may now EMOTE anywhere.\n", (psex(pl) ? FLevels : MLevels)[LVL_FIFTEEN]); break; case LVL_APPREN: if (cur_player->defrob != NULL) break; set_xpflags(LVL_APPREN, &pflags(pl), &pmask(pl) ); /* Player can't be in a group anymore. */ if (IN_GROUP(pl)) { if (P_GROUP_LEADER(pl) == pl) { int plx; setup_globals(pl); /* Drop the whole group. */ sprintf(globalbuf,"Party is disbanded"); partyannounce(globalbuf); for (plx =0 ; plx < max_players; plx++) { if (is_in_game(plx) && (P_GROUP(plx) == P_GROUP(pl)) && plx != pl) { leaveplayer(plx); } } /* Now only the leader is in the group */ P_GROUP_SHARES(pl) -= P_SHARE(pl); P_SHARE(pl) = 0; free(P_GROUP(pl)); /* Loose allocated mem */ P_GROUP(pl) = NULL; } else { setup_globals(pl); sprintf(globalbuf,"%s has left the party",pname(pl)); partyannounce(globalbuf); leaveplayer(pl); } } sendf(DEST_ALL,"&+wTrumpets sounds praise %s the new Wizard!&+w\n", pname(pl) ); sendf(pl, "\001f%s\003",GWIZ); update_wizlist(pname(pl), LEV_APPRENTICE); break; default: sendf(pl,"Keep up the good work.\n"); break; } } /* if (pstr(pl) > (b = maxstrength(pl))) setpstr(pl,b); */ } void calibme () { calib_player (mynum); } void destroy_mobile (int mob) { setploc (mob, dead_loc); } int levelof (int score, int lev) { int i; if (lev > LVL_APPREN || lev < LVL_ONE) return lev; for (i = LVL_APPREN; i > LVL_GUEST; i--) if (score >= levels[i]) return i; return 0; } Boolean check_busy (int plx) { if (ststflg (plx, SFL_BUSY)) { bprintf ("%s is busy, try later!\n", pname (plx)); return True; } return False; } /*************************************************************************** ** Flexible prompting routine. Builds a prompt everytime it's needed, ** giving up to date information. ** Author: Marty 1997 **************************************************************************/ char *build_prompt(int plx) { int i,len; char *format; static char buffer2[3*PROMPT_LEN]; /* Second step build buffer */ static char buffer[3*PROMPT_LEN]; /* First step build buffer */ char *p = buffer; Boolean fightmsg = False; if (plx < 0 || plx >= max_players) return ">"; format = players[plx].prompt; if (format == NULL || buffer == NULL) return NULL; len = strlen(format); *p = '\0'; if (pvis(plx) > 0) /* The () around an invis prompt */ { strcat(p,"&+w("); p += strlen(p); } if (players[plx].aliased) { strcat(p,"&+w@&*"); p += strlen(p); } for (i = 0; i < len && strlen(buffer2) < (PROMPT_LEN *2) ; i++) { if (format[i] == '%') { switch (format[i+1]) { case '%' : *p = format[i++]; break; case 'h' : if (pstr(plx) == 0) sprintf(p,"&+w0"); else sprintf(p,"&+%c%d",(maxstrength(plx) / pstr(plx) >= 3 || pstr(plx) < 0) ? 'R' : (maxstrength(plx) / pstr(plx) >= 2) ? 'Y' : 'G', pstr(plx)); p += strlen(p); i++; fightmsg = True; break; case 'H' : sprintf(p,"%d",maxstrength(plx)); p += strlen(p); i++; break; case 'S' : case 's' : sprintf(p,"%d",pscore(plx)); p += strlen(p); i++; break; case 'Q' : sprintf(p,"%d",qp_for_level(plev(plx))); p += strlen(p); i++; break; case 'q' : sprintf(p,"%d",qpoints(plx)); p += strlen(p); i++; break; case 'D' : case 'd' : { int dam; int obdam = (pwpn(plx) == -1 || pwpn(plx) > numobs) ? 0 : odamage(pwpn(plx)); dam = pdam(plx) + obdam; if (dam < 10) sprintf(p,"D:&+w.&*"); else if (dam < 20) sprintf(p,"D:&+w+&*"); else if (dam < 32) sprintf(p,"D:&+w*&*"); else sprintf(p,"D:&+wo&*"); p += strlen(p); i++; break; } case 'A': case 'a': { int plxarm = player_armor(plx); if (plxarm < 10) sprintf(p,"A:&+w.&*"); else if (plxarm < 25) sprintf(p,"A:&+w+&*"); else if (plxarm < 48) sprintf(p,"A:&+w*&*"); else sprintf(p,"A:&+wo&*"); p += strlen(p); i++; break; } default: } } else { *p = format[i]; p++; } } if (pvis(plx) > 0) sprintf(p,"&+w)&*"); else sprintf(p,"&*"); p += strlen(p); *p = '\0'; buffer2[0] = '\0'; if (pfighting(plx) >= 0 && !fightmsg) { if (pstr(plx) > 0) sprintf(buffer2,"&+w[&+%c%d&+L/&+w%d&+w]",(maxstrength(plx) / pstr(plx) >= 3) ? 'R' : (maxstrength(plx) / pstr(plx) >= 2) ? 'Y' : 'G', pstr(plx),maxstrength(plx)); else sprintf(buffer2,"&+w[&+w0&+L/&+w%d&+w]",maxstrength(plx)); } else return buffer; /* Not going to strcat to nothing, only takes time*/ strcat(buffer2,buffer); return buffer2; } int vicf2 (int fl, int i) { int plr; if (ltstflg (ploc (mynum), LFL_NO_MAGIC) != 0 && plev (mynum) < LVL_APPREN) { bprintf ("Something about this location has drained your mana.\n"); return -1; } if (fl >= SPELL_VIOLENT && plev (mynum) < LVL_APPREN && testpeace (mynum)) { bprintf ("No, that's violent!\n"); return -1; } if ((plr = vicbase ()) < 0) return -1; if (pstr (mynum) < 10) { bprintf ("You are too weak to cast magic.\n"); return -1; } if (plev (mynum) < LVL_APPREN) setpstr (mynum, pstr (mynum) - 5); i += has_magic_object(mynum); i /= 2; if (plev (mynum) < LVL_APPREN && randperc () > i * plev (mynum)) { bprintf ("You fumble the magic.\n"); if (fl == SPELL_REFLECTS) { bprintf ("The spell reflects back.\n"); return mynum; } return -1; } if (plr < max_players && plr >= 0) { if (players[plr].linkdead && plev(mynum) < LVL_ARCHWIZARD) { bprintf("%s is linkdead and can't be affected by your actions.\n", pname(plr)); return -1; } } if (plev (mynum) < LVL_APPREN) { Boolean has_shield = wearsobjfrom(plr,sp_shields); if ((fl >= SPELL_VIOLENT) && has_shield) { bprintf ("The spell is absorbed by %s shield!\n", his_or_her (plr)); return -1; } } bprintf ("The spell succeeds!\n"); return plr; } int vichfb (int cth) { int a; if ((a = vicf2 (SPELL_VIOLENT, cth)) < 0) return a; if (ploc (a) != ploc (mynum)) { bprintf ("%s isnt here.\n", psex (a) ? "She" : "He"); return -1; } return a; } int vichere (void) { int a; if ((a = vicbase ()) == -1) return -1; if (ploc (a) != ploc (mynum)) { bprintf ("They aren't here.\n"); return -1; } return a; } int vicbase (void) { int a; do { if (brkword () == -1) { bprintf ("Who?\n"); return -1; } } while (EQ (wordbuf, "at")); if ((a = fpbn (wordbuf)) < 0) { bprintf ("That person isn't playing now.\n"); return -1; } return a; } /* The JUMP command */ A_COMMAND(jumpcom) { int a, b, i, j, x; char ms[128]; if (psitting (mynum)) { bprintf ("You have to stand up first.\n"); return; } /* Search the jump-table for special locations.. */ for (a = 0, b = 0; jumtb[a]; a += 2) { if (jumtb[a] == ploc (mynum)) { b = jumtb[a + 1]; break; } } if (rom_fun(ploc(mynum)) != NULL) { param_s.plx = mynum; param_s.loc = ploc(mynum); param_s.to = b; rom_fun(ploc(mynum))(E_ONJUMP); if (param_s.ret != 1) return; } /* Are we by a pit ? If so we'll jump into it. */ for (i = 0; (j = pit_jumptb[i]) != -1 && oloc (j) != ploc (mynum);i += 2) ; if (pit_jumptb[i] != -1) b = pit_jumptb[i+1]; if (b == 0) { bprintf ("&+wWheeeeee....&*\n"); return; } if ((x = carries_obj_type (mynum, Umbrella_Obj)) > -1 && state (x) != 0) { sprintf (ms, "%s jumps off the ledge.\n", pname (mynum)); bprintf ("You grab hold of the %s and fly down like " "Mary Poppins.\n", oname (x)); } else if (plev (mynum) < LVL_APPREN) { sprintf (ms, "%s makes a perfect swan dive off the ledge.\n", pname (mynum)); if (b != pit_loc) { send_msg (ploc (mynum), 0, pvis (mynum), LVL_MAX, mynum, NOBODY, ms); setploc (mynum, b); bprintf ("&+wWheeeeeeeeeeeeeeeee&* <<<<SPLAT>>>>\n" "You seem to be splattered all over the place.\n"); crapup ("\t\tI suppose you could be scraped up with a spatula.", SAVE_ME); } } else sprintf (ms, "%s dives off the ledge and floats down.\n", pname (mynum)); send_msg (ploc (mynum), 0, pvis (mynum), LVL_MAX, mynum, NOBODY, ms); setploc (mynum, b); if (iscarrby (Umbrella_Obj, mynum)) sprintf (ms, "%s flys down, clutching an umbrella.\n", pname (mynum)); else sprintf (ms, "%s has just dropped in.\n", pname (mynum)); send_msg (ploc (mynum), 0, pvis (mynum), LVL_MAX, mynum, NOBODY, ms); trapch (b); } /**************************************************************************** ** BOOZE and DRUNK code. Show some messages at random intervals, and count ** down the time untill a player is sober. Marty 1996 ****************************************************************************/ void do_drunk(int plx) { if (randperc() < 15) { if (pdrunk(plx) < 3) { send_msg(ploc(plx),0,LVL_MIN,LVL_MAX,plx,NOBODY, "\001p%s\003 feels a bit dazed.\n",pname(plx)); sendf(plx,"You feel a bit dazed.\n"); } else if (pdrunk(plx) < 8) { send_msg(ploc(plx),0,LVL_MIN,LVL_MAX,plx,NOBODY, "\001p%s\003 feels a bit light headed.\n",pname(plx)); sendf(plx,"You feel a bit light headed.\n"); } else if (pdrunk(plx) < 15) { send_msg(ploc(plx),0,LVL_MIN,LVL_MAX,plx,NOBODY, "\001p%s\003 burps loudly.\n",pname(plx)); sendf(plx,"You burp loudly.\n"); } else if (pdrunk(plx) < 24) { sendf(plx,"The &+ww&+wo&+wr&+wl&+wd&* starts to spin.\n"); send_msg(ploc(plx),0,LVL_MIN,LVL_MAX,plx,NOBODY, "\001p%s\003 looks a bit drunk.\n",pname(plx)); } else { send_msg(ploc(plx),0,LVL_MIN,LVL_MAX,plx,NOBODY, "\001p%s\003 suddenly starts to &+wpuke&*!\n",pname(plx)); sendf(plx,"You &+wpuke&* all over the floor!\n"); } } /* Decrease the time a player is drunk, clear flag is player is sober */ setpdrunk(plx,pdrunk(plx)--); if (pdrunk(plx) == 0) sclrflg(plx,SFL_DRUNK); } void do_trace(int plr) { TRACE *tr; static char b[512], b1[80]; int x,r,l; tr = &players[plr].tr; x = tr->trace_item; switch (tr->trace_class) { case 2: if (is_in_game(x)) { if (ploc(x) != tr->trace_loc) { sendf(plr,"&+w[&+wTRACE&+w: %s is now at %s&+w]&*\n", pname(x), showname(ploc(x))); tr->trace_loc = ploc(x); } } else { sendf(plr,"&+w[&+wTRACE&+w: Person/Mobile has departed from the game&+w]&*\n"); tr->trace_item = -1; } break; case 1: if (oloc(x) != tr->trace_loc || ocarrf(x) != tr->trace_carrf || tr->trace_oroom != roomobjin(x)) { r = roomobjin(x); l = oloc(x); if (r == pit_loc) { sprintf("&+w[&+wTRACE&+w: %s has been dropped in the pit&+w]&*\n",oname(x)); tr->trace_item = -1; return; } sprintf(b,"&+w[&+wTRACE&+w: %s is",oname(x)); tr->trace_loc = oloc(x); tr->trace_carrf = ocarrf(x); tr->trace_oroom = r; while (ocarrf(x) == IN_CONTAINER) { sprintf(b1," in the %s", oname(l)); strcat(b,b1); x = l; l = oloc(x); } switch (ocarrf(x)) { case CARRIED_BY: sprintf(b1," carried by %s", pname(oloc(x))); break; case WORN_BY: sprintf(b1," worn by %s", pname(oloc(x))); break; case WIELDED_BY: sprintf(b1," wielded by %s", pname(oloc(x))); break; case BOTH_BY: sprintf(b1," worn and wielded by %s",pname(oloc(x))); break; default: } strcat(b,b1); sprintf(b1," in %s&+w]&*\n",showname(r)); strcat(b,b1); sendf(plr,b); } break; default: mudlog("TRACE: Error in trace, wrong type.\n"); sendf(plr,"&+w[&+wTRACE&+w: Aborted, data screwup&+w]&*\n"); tr->trace_item = -1; } } /* Stuff that should be done both after every command and at every * i/o-interrupt at the latest. */ void special_events (int player) { int start = (player == SP_ALL) ? 0 : player; int stop = (player == SP_ALL) ? max_players - 1 : player; /*max_chars ? */ int i; int r_fig; /* cut down on randoms */ Boolean has_amulet; if (player >= max_players) return; for (i = start; i <= stop; ++i) if (is_in_game (i)) { calib_player(i); r_fig= randperc(); if (players[i].tr.trace_item != -1) { do_trace(i); } if (plev (i) < LVL_APPREN && ltstflg (ploc (i), LFL_ON_WATER)) { if (!carries_boat (i)) { p_crapup (i, "\t\tYou plunge beneath the waves....", CRAP_SAVE); continue; } } has_amulet = (wearsobjfrom(i,amulets) || !players[i].iamon || plev(i) >= LVL_WIZARD); if (ltstflg(ploc(i),LFL_IN_WATER)) { if (!has_amulet) { p_crapup(i, "\t\t&+wWater rushes in to fill your lungs....&+w", CRAP_SAVE); broad("In this distance you hear some splashing and a gurgle.\n"); continue; } if ( randperc() <= 5) sendf(i,"You notice &+wair bubbles&+w floating up as you exhale.\n"); } if (ltstflg(ploc(i),LFL_AIRLESS)) { if (!has_amulet) { sendf(i,"You gasp for air, but there is no atmosphere here you can breathe.\n"); p_crapup(i,"\t\tYou died by suffocation.",CRAP_SAVE); continue; } } /* * If you are underwater and have an extinguishable light, KILL IT! */ if (ltstflg(ploc(i),LFL_IN_WATER)) { int x; for(x=0;x<numobs;x++) if(iscarrby(x,i) && otstbit(x,OFL_LIT) && otstbit(x, OFL_EXTINGUISH)) { sendf (i, "The &+wwater&* promptly extingishues your %s!\n", oname(x)); oclrbit(x,OFL_LIT); } } if (ltstflg(ploc(i),LFL_AIRLESS)) { int x; for(x=0;x<numobs;x++) if(iscarrby(x,i) && otstbit(x,OFL_LIT) && otstbit(x, OFL_EXTINGUISH)) { sendf (i, "The %s promptly extingishues because of lack of oxygen!\n", oname(x)); oclrbit(x,OFL_LIT); } } /* SPECIAL EVENTS */ param_s.plx = i; check_obj_in_room(i,E_ONTIMER); check_pl_in_room(i,E_ONTIMER); check_obj_on_plx(i,E_ONTIMER); if (rom_fun(ploc(i)) != NULL) { rom_fun(ploc(i))(E_ONTIMER); if (param_s.ret == -1) continue; } if (ublock[Puff_The_Dragon+max_players].spec_case != NULL) { if (alive(Puff_The_Dragon+max_players) != -1) { param_s.pl = Puff_The_Dragon+max_players; param_s.loc = ploc(param_s.pl); ublock[Puff_The_Dragon+max_players].spec_case(E_ONTIMER); } } /* END SPECIAL EVENTS */ /* If the snoop-victim has disappeard or the snooper is (only) a wizard * * and the target has gone into a private room, then stop the snoop. */ if (players[i].snooptarget != -1) { if (!is_in_game (players[i].snooptarget)) { sendf (i, "You can no longer snoop.\n"); snoop_off (i); } else if (ltstflg (ploc (players[i].snooptarget), LFL_PRIVATE) && plev (i) < LVL_ARCHWIZARD) { sendf (i, "%s went into a PRIVATE room, you can no longer snoop.\n", pname (players[i].snooptarget)); snoop_off (i); } } /* count down if polymorphed */ if (players[i].polymorphed == 0) unpolymorph (i); if (players[i].polymorphed > -1) players[i].polymorphed--; /* if invis, count down */ if (players[i].me_ivct > 0 && --players[i].me_ivct == 0) setpvis(i,0); /* Make people loose drunk, only on timer, so it doesnt matter * how many commands you type in a second ;) */ if (pdrunk(i) > 0 && player == SP_ALL) do_drunk(i); if (pstr (i) < 0 && (players[i].aliased || players[i].polymorphed != -1)) { sendf (i, "You've just died.\n"); if (players[i].polymorphed != -1) unpolymorph (i); else unalias (i); } } /* end for each player */ } void regenerate (void) { /* chance of heal is now 15 and 30 instead of 20 and 40 since * the interrupt now occurs every 2 secs. instead of 3 */ int i; int r_fig = randperc(); Boolean has_ring; Boolean has_heal_obj = False; for (i = 0; i < max_players; ++i) if (is_in_game (i) && pfighting (i) < 0 && pstr (i) < maxstrength (i) && players[i].linkdead == False) { has_ring = (wears_obj_type (i, Tower_Ring_Obj) > -1); has_heal_obj = (p_ohanyflag(i,OFL_FASTHEAL) >= 0); r_fig=randperc(); /* Only one random call per player */ if (ststflg(i,SFL_POISONED) && r_fig < 50) { sendf(i,"You feel the poison slowly crawling through your veins draining your strength\n"); setpstr(i,pstr(i) - 1); continue; } if ((r_fig < 15) && ltstflg(ploc(i), LFL_NEG_REGEN) && (!has_ring && pstr(i) > 1) && plev(i) < LVL_APPREN) { sendf(i, "You feel your energy draining away!\n"); setpstr( i, pstr(i) - 1); continue; } if (((!has_ring && (randperc() < 25)) || ((psitting (i) && randperc() < 40))) || ((psitting(i)==2 && randperc() <60)) || ((has_ring && randperc() < 67)) || (psitting(i)==3 && ptstflg(i,PFL_CANTRANCE) && randperc() < 70) || (has_heal_obj && randperc() < 74) || (pdrunk(i) > 0 && randperc() < pdrunk(i) * 10) ) { if (maxstrength (i) == pstr (i) + 1) { sendf (i, "You feel fully healed.\n"); } setpstr (i, pstr (i) + 1); if (players[i].iamon) calib_player (i); } } } static void _userlist (char mode) { char line[256]; char locname[80]; register int t; /* int old_mynum = 0;*/ int a[256], a_len = 0; int idle = 0; struct tm *tm; int j; char buff[10]; char uname[20]; int usercount = 0; Boolean show_hostname = False; Boolean show_location = False; Boolean notHere = False; if (cur_player->aliased || cur_player->polymorphed != -1) { bprintf("Not while aliased.\n"); return; } if (the_world->w_tournament || plev (mynum) >= LVL_APPREN) show_location = True; if (ptstflg (mynum, PFL_SHUSER) || the_world->w_tournament) show_hostname = True; if (mode) { bprintf("&+wLevel Player&*\n"); bprintf ("&+w%s&+w\n",DASHLINE); } else { bprintf ("&+w%-7s %-12.12s %-16.16s %-8.8s %-10.10s %-21.21s&+w\n", "Level", "Player", show_hostname ? "Hostname" : " ", "Idle", show_location ? "Zone" : " ", show_location ? "Room" : " "); bprintf ("&+w%s&*\n",MIXLINE); } for (t=0; t<max_players; t++) if (is_in_game(t) && ((pvis(t) <= plev(mynum)) || (t == mynum))) { a[a_len++]=t; } qsort( a, a_len, sizeof(int), cmp_player); for (j = 0; t = a[j], j < a_len; ++j) { idle = time(0) - players[t].last_command; tm = (struct tm *)gmtime((const time_t *)&idle); if ((plev(t) < LVL_APPREN && idle > 180) || (plev(t) >= LVL_APPREN && (idle > 300))) notHere = True; if (EQ(pname(t),"Marty")) { strcpy(uname,"HellSpawn"); } else { lev2s(uname, plev(t), psex(t)); uname[strlen(uname) -1] = '\0'; } if (mode) { Boolean nocomm = ststflg(t,SFL_NOCOMM); if (ststflg(t,SFL_AWAY)) sprintf (line, "&+w[&+w%-9.9s&+w]&+w%c&* %s is away, %s\n",uname,(pvis(t) > 0) ? '*' : ' ', pname(t),players[t].awaymsg); else sprintf (line, "&+w[&+w%-9.9s&+w]&+w%c&* %s&+w%s%s%s%s%s%s%s%s%s%s%s%s&+w\n", uname, (pvis(t) > 0) ? '*' : ' ', t < max_players ? make_title (ptitle(t), pname(t)) : "&+w[Possessed&*]", players[t].linkdead ? " &+w(&+wlinkdead&+w)&+w" : "", players[t].defrob != NULL ? " [Asmortal]" : "", /* Show party name */ whopartytst(t), (ststflg(t, SFL_NOSHOUT) && !nocomm) ? " [NoShout]" : "", (ststflg(t, SFL_NO_GOSSIP) && !nocomm) ? " [NoGossip]" : "", (ststflg(t, SFL_NO_CHAT) && !nocomm) ? " [NoChat]" : "", ststflg(t, SFL_BUSY) ? " [Busy]" : "", ststflg(t, SFL_CODING) ? " [Coding]" : "", (ststflg(t, SFL_NO_WIZ) && !nocomm && plev(mynum) >= LVL_APPREN) ? " [NoWiz]" : "", (notHere && !players[t].linkdead) ? " [Idle]" : "", (ststflg(t, SFL_DISTRACTED) && !players[t].inmailer) ? " [Distracted]" : "", players[t].inmailer ? " &+w[&+wMailing&+w]&+w" : "" ); notHere = False; } else { idle = time (0) - players[t].last_cmd; tm = (struct tm *) gmtime ((const time_t *)&idle); strftime (buff, 10, "%H:%M:%S", tm); sprintf(line, "&+w[&+w%5d&+w]&+w%s%-12.12s&* &+w%-16.16s&* &+w%-8.8s&* &+w%-10.10s&+w %-s\n", plev(t), (pvis(t) > 0) ? "*" : " ", pname (t), show_hostname ? players[t].hostname : " ", buff, show_location ? showname (ploc (t)) : " ", show_location ? bstrncpy(locname,sdesc(ploc(t)),19) : " "); } if (((pvis (t) <= plev (mynum)) || t == mynum) && strlen (pname (t))) { usercount++; bprintf ("%s",line); } } bprintf ("&+w%s\n&+wA total of &+w%d&+w visible users.\n", (mode) ? DASHLINE : MIXLINE, usercount); return; } void show_mob_strength(int plx) { int x,p; static char *t[] = { "%s near death.&*\n", "%s near death.&*\n", "%s mortally wounded.&*\n", "%s seriously wounded.&*\n", " some wounds, but %s still fairly strong.&*\n", " minor cuts and abrasions.&*\n", " minor cuts and abrasions.&*\n", " feels a bit dazed.&*\n", "%s in better than average condition.&*\n", "%s in exceptional health.&*\n", "%s in exceptional health.&*\n" }; if (plx >= max_players) { x = pstr_reset (plx); } else { x = maxstrength (plx); } if (pstr(plx) < 0) p = -1; else if (pstr(plx) == 0 || x == 0) p =0; else if (pstr(plx) > x) p = 11; else p = (int) (pstr(plx) * 10 / x); bprintf("&+w%s&* ", pname(plx)); if (p >= 4 && p <= 6) bprintf ("&+w%s&*", "&+whas"); if (p >= 0 && p <= 10) bprintf (t[p], "&+wis"); else bprintf ("&+wmust %s&*", p < 0 ? "&+wbe undead!&*\n" : "&+whave had Wheaties for breakfast!&*\n"); } char *short_mob_strength(int plx) { int x,p; static char *t[] = { "near death", "near death", "mortally wounded", "seriously wounded", "fairly strong", "minor cuts and abrasions", "minor cuts and abrasions", "dazed", "average condition", "exceptional health", "excellent health" }; if (plx >= max_players) { x = pstr_reset (plx); } else { x = maxstrength (plx); } if (pstr(plx) < 0) p = -1; else if (pstr(plx) > x) p = 11; else if (pstr(plx) == 0 || x == 0) p = 0; else p = (int) (pstr(plx) * 10 / x); if (p < ARRAYSIZE(t) && p >= 0) return t[p]; else return (p < 0 ? "&+Lundead!&*" : "&+wSuperman!&*"); }