/************************************************************************** * Original Diku Mud copyright (C) 1990, 1991 by Sebastian Hammer, * * Michael Seifert, Hans Henrik St{rfeldt, Tom Madsen, and Katja Nyboe. * * * * Merc Diku Mud improvements copyright (C) 1992, 1993 by Michael * * Chastain, Michael Quan, and Mitchell Tse. * * * * In order to use any part of this Merc Diku Mud, you must comply with * * both the original Diku license in 'license.doc' as well the Merc * * license in 'license.txt'. In particular, you may not remove either of * * these copyright notices. * * * * Much time and thought has gone into this software and you are * * benefiting. We hope that you share your changes too. What goes * * around, comes around. * *************************************************************************** * ROM 2.4 is copyright 1993-1998 Russ Taylor * * ROM has been brought to you by the ROM consortium * * Russ Taylor (rtaylor@hypercube.org) * * Gabrielle Taylor (gtaylor@hypercube.org) * * Brian Moore (zump@rom.org) * * By using this code, you have agreed to follow the terms of the * * ROM license, in the file Rom24/doc/rom.license * *************************************************************************** * 1stMUD ROM Derivative (c) 2001-2003 by Ryan Jennings * * http://1stmud.dlmud.com/ <r-jenn@shaw.ca> * ***************************************************************************/ #include "merc.h" #include "globals.h" #include "recycle.h" #include "interp.h" #include "tables.h" //Attempting to guess URL with hostname and username //www url of the directory with mud images #define IMAGE_URL FORMATF("http://www.%s/~%s/images", HOSTNAME, UNAME) //www url of the directory with mud sounds #define SOUND_URL FORMATF("http://www.%s/~%s/msp", HOSTNAME, UNAME) void setup_mxp(DESCRIPTOR_DATA * d) { if (!IS_MXP(d)) return; d_print(d, MXPTAG ("!ELEMENT RName '<FONT COLOR=Green>;<B>;' FLAG=\"RoomName\""), 0); d_print(d, MXPTAG("!ELEMENT RDesc FLAG='RoomDesc' OPEN"), 0); d_print(d, MXPTAG ("!ELEMENT RExits '<FONT COLOR=Blue>;' FLAG='RoomExit' OPEN"), 0); d_print(d, MXPTAG("!ELEMENT Ex '<SEND>;'"), 0); d_print(d, MXPTAG("!ELEMENT Prompt FLAG=\"Prompt\" OPEN"), 0); d_print(d, MXPTAG("!ELEMENT Hp FLAG=\"Set hp\" OPEN"), 0); d_print(d, MXPTAG("!ELEMENT MaxHp FLAG=\"Set maxhp\" OPEN"), 0); d_print(d, MXPTAG("!ELEMENT Mana FLAG=\"Set mana\" OPEN"), 0); d_print(d, MXPTAG("!ELEMENT MaxMana FLAG=\"Set maxmana\" OPEN"), 0); d_print(d, MXPTAG("!ELEMENT Move FLAG=\"Set move\" OPEN"), 0); d_print(d, MXPTAG("!ELEMENT MaxMove FLAG=\"Set maxmove\" OPEN"), 0); /* Bid an item tag (for things in the auction) */ d_print(d, MXPTAG ("!ELEMENT Bid \"<send href='bid '&name;'' " "hint='Bid for &desc;' prompt>\" ATT='name desc'"), 0); d_print(d, MXPTAG ("!ELEMENT Help \"<send href='help '&name;'' " "hint='Help on &desc;'>\" ATT='name desc'"), 0); /* List an item tag (for things in a shop) */ d_print(d, MXPTAG ("!ELEMENT List \"<send href='buy '&name;'' " "hint='Buy &desc;'>\" ATT='name desc'"), 0); /* Player tag (for who lists, tells etc.) */ d_print(d, MXPTAG ("!ELEMENT Tell \"<send href='tell '&name;' ' " "hint='print a message to &name;' prompt>\" ATT='name'"), 0); d_print(d, MXPTAG ("!ELEMENT Fwho \"<send href='whois '&name;'|" "buddy '&name;'' " "hint='Right mouse click to use this object|Whois &desc;|" "Buddy &desc;'>\" ATT='name desc'"), 0); d_print(d, MXPTAG ("!ELEMENT Olc \"<send href='commands|show|done' " "hint='Show commands|Show|Finish editing'>\""), 0); return; } void init_mxp(DESCRIPTOR_DATA * d) { d_print(d, MXPTAG("VERSION"), 0); d_print(d, MXPTAG("SUPPORT"), 0); } CH_CMD(do_mxp) { if (!ch->desc || IS_NPC(ch)) { chprintln(ch, "No descriptor."); return; } set_on_off(ch, &ch->desc->d_flags, DESC_MXP, "MUD eXtension Protocol enabled.", "MUD eXtension Protocol disabled."); if (IS_SET(ch->desc->d_flags, DESC_MXP)) { if ((ch->desc->mxp.mxp_ver * 10) < 4) init_mxp(ch->desc); else setup_mxp(ch->desc); } } /* * Count number of mxp tags need converting * ie. < becomes < * > becomes > * & becomes & */ int count_mxp_tags(DESCRIPTOR_DATA * d, const char *txt, int length) { char c; const char *p; int count; bool bInTag = FALSE; bool bInEntity = FALSE; bool bMXP = IS_SET(d->d_flags, DESC_MXP); for (p = txt, count = 0; length > 0; p++, length--) { c = *p; if (bInTag) /* in a tag, eg. <send> */ { if (!bMXP) count--; /* not output if not MXP */ if (c == MXP_ENDc) bInTag = FALSE; } /* end of being inside a tag */ else if (bInEntity) /* in a tag, eg. <send> */ { if (!bMXP) count--; /* not output if not MXP */ if (c == ';') bInEntity = FALSE; } /* end of being inside a tag */ else switch (c) { case MXP_BEGc: bInTag = TRUE; if (!bMXP) count--; /* not output if not MXP */ else count += 4; /* allow for ESC [1z */ break; case MXP_ENDc: /* shouldn't get this case */ if (!bMXP) count--; /* not output if not MXP */ break; case MXP_AMPc: bInEntity = TRUE; if (!bMXP) count--; /* not output if not MXP */ break; default: if (bMXP) { switch (c) { case '<': /* < becomes < */ case '>': /* > becomes > */ count += 3; break; case '&': count += 4; /* & becomes & */ break; case '"': /* " becomes " */ count += 5; break; } /* end of inner switch */ } /* end of MXP enabled */ } /* end of switch on character */ } /* end of counting special characters */ return count; } /* end of count_mxp_tags */ void convert_mxp_tags(DESCRIPTOR_DATA * d, char *dest, const char *src, int length) { char c; const char *ps; char *pd; bool bInTag = FALSE; bool bInEntity = FALSE; bool bMXP = IS_SET(d->d_flags, DESC_MXP); for (ps = src, pd = dest; length > 0; ps++, length--) { c = *ps; if (bInTag) /* in a tag, eg. <send> */ { if (c == MXP_ENDc) { bInTag = FALSE; if (bMXP) { *pd++ = '>'; } } else if (bMXP) *pd++ = c; /* copy tag only in MXP mode */ } /* end of being inside a tag */ else if (bInEntity) /* in a tag, eg. <send> */ { if (bMXP) *pd++ = c; /* copy tag only in MXP mode */ if (c == ';') bInEntity = FALSE; } /* end of being inside a tag */ else switch (c) { case MXP_BEGc: bInTag = TRUE; if (bMXP) { memcpy(pd, MXPMODE(1), 4); pd += 4; *pd++ = '<'; } break; case MXP_ENDc: /* shouldn't get this case */ bInTag = FALSE; if (bMXP) { *pd++ = '>'; } break; case MXP_AMPc: bInEntity = TRUE; if (bMXP) *pd++ = '&'; break; default: if (bMXP) { switch (c) { case '<': memcpy(pd, "<", 4); pd += 4; break; case '>': memcpy(pd, ">", 4); pd += 4; break; case '&': memcpy(pd, "&", 5); pd += 5; break; case '"': memcpy(pd, """, 6); pd += 6; break; default: *pd++ = c; break; /* end of default */ } /* end of inner switch */ } else *pd++ = c; /* not MXP - just copy character */ break; } /* end of switch on character */ } /* end of converting special characters */ } /* end of convert_mxp_tags */ const char *mxp_obj(OBJ_DATA * obj, CHAR_DATA * ch, bool fShort) { if (!obj) return "!bug!"; if (!ch || !IS_MXP(ch->desc)) return fShort ? obj->short_descr : obj->description; if (obj->in_room) { } else if (obj->in_obj) { } else if (obj->in_room) { } else { } return fShort ? obj->short_descr : obj->description; } const char *mxp_char(CHAR_DATA * mch, CHAR_DATA * ch, bool fShort) { if (!mch) return "!bug!"; if (!ch || !IS_MXP(ch->desc)) return fShort ? mch->short_descr : mch->long_descr; if (mch->in_room == ch->in_room) { } return fShort ? mch->short_descr : mch->long_descr; } const char *create_tag(CHAR_DATA * ch, const char *text, const char *hint, const char *command, ...) { va_list args; char format[MSL]; static char buf_new[5][MSL]; static int i; char *result; if (!ch || !ch->desc || IS_NULLSTR(command)) return text; // rotate buffers ++i; i %= 5; result = buf_new[i]; va_start(args, command); vsnprintf(format, sizeof(format), command, args); va_end(args); if (IS_MXP(ch->desc)) { if (!IS_NULLSTR(hint)) sprintf(result, MXPTAG("send href='%s' hint='%s'") "%s" MXPTAG("/send"), format, hint, text); else sprintf(result, MXPTAG("send href='%s'") "%s" MXPTAG("/send"), format, text); } else if (IS_PUEBLO(ch->desc)) { if (!IS_NULLSTR(hint)) sprintf(result, "</xch_mudtext><img xch_mode=html><a xch_cmd=\"%s\" xch_hint=\"%s\">" "%s</a><br><img xch_mode=text>", format, hint, text); else sprintf(result, "</xch_mudtext><img xch_mode=html><a xch_cmd=\"%s\">" "%s</a><br><img xch_mode=text>", format, text); } else return text; return (result); } const struct flag_type mxp_support_flags[] = { {"a", BIT_A, FALSE}, {"a.href", BIT_B, FALSE}, {"a.xch_cmd", BIT_C, FALSE}, {"a.xch_hint", BIT_D, FALSE}, {"b", BIT_E, FALSE}, {"body", BIT_F, FALSE}, {"bold", BIT_G, FALSE}, {"br", BIT_H, FALSE}, {"c", BIT_I, FALSE}, {"c.back", BIT_J, FALSE}, {"c.fore", BIT_K, FALSE}, {"color", BIT_L, FALSE}, {"color.back", BIT_M, FALSE}, {"color.fore", BIT_N, FALSE}, {"em", BIT_O, FALSE}, {"expire", BIT_P, FALSE}, {"font", BIT_Q, FALSE}, {"font.back", BIT_R, FALSE}, {"font.bgcolor", BIT_S, FALSE}, {"font.color", BIT_T, FALSE}, {"font.fgcolor", BIT_U, FALSE}, {"gauge", BIT_V, FALSE}, {"h", BIT_W, FALSE}, {"head", BIT_X, FALSE}, {"high", BIT_Y, FALSE}, {"hr", BIT_Z, FALSE}, {"html", BIT_a, FALSE}, {"i", BIT_b, FALSE}, {"image", BIT_c, FALSE}, {"image.url", BIT_d, FALSE}, {"img", BIT_e, FALSE}, {"img.src", BIT_f, FALSE}, {"img.xch_mode", BIT_Ax, FALSE}, {"italic", BIT_Bx, FALSE}, {"li", BIT_Cx, FALSE}, {"music", BIT_Dx, FALSE}, {"mxp", BIT_Ex, FALSE}, {"mxp.off", BIT_Fx, FALSE}, {"nobr", BIT_Gx, FALSE}, {"ol", BIT_Hx, FALSE}, {"option", BIT_Ix, FALSE}, {"p", BIT_Jx, FALSE}, {"pass", BIT_Kx, FALSE}, {"password", BIT_Lx, FALSE}, {"pre", BIT_Mx, FALSE}, {"relocate", BIT_Nx, FALSE}, {"reset", BIT_Ox, FALSE}, {"s", BIT_Px, FALSE}, {"samp", BIT_Qx, FALSE}, {"sbr", BIT_Rx, FALSE}, {"send", BIT_Sx, FALSE}, {"send.hint", BIT_Tx, FALSE}, {"send.href", BIT_Ux, FALSE}, {"send.prompt", BIT_Vx, FALSE}, {"send.xch_cmd", BIT_Wx, FALSE}, {"send.xch_hint", BIT_Xx, FALSE}, {"sound", BIT_Yx, FALSE}, {"stat", BIT_Zx, FALSE}, {NULL, 0, FALSE} }; const struct flag_type mxp_support_flags2[] = { {"strike", BIT_A, FALSE}, {"strong", BIT_B, FALSE}, {"support", BIT_C, FALSE}, {"title", BIT_D, FALSE}, {"u", BIT_E, FALSE}, {"ul", BIT_F, FALSE}, {"underline", BIT_G, FALSE}, {"user", BIT_H, FALSE}, {"username", BIT_I, FALSE}, {"v", BIT_J, FALSE}, {"var", BIT_K, FALSE}, {"version", BIT_L, FALSE}, {"xch_page", BIT_M, FALSE}, {"dd", BIT_N, FALSE}, {"dest", BIT_O, FALSE}, {"dl", BIT_P, FALSE}, {"dt", BIT_Q, FALSE}, {"frame", BIT_R, FALSE}, {"h1", BIT_S, FALSE}, {"h2", BIT_T, FALSE}, {"h3", BIT_U, FALSE}, {"h4", BIT_V, FALSE}, {"h5", BIT_W, FALSE}, {"h6", BIT_X, FALSE}, {"small", BIT_Y, FALSE}, {"tt", BIT_Z, FALSE}, {"xch_mudtext", BIT_a, FALSE}, {"xch_pane", BIT_b, FALSE}, {NULL, 0, FALSE} }; flag_t mxp_lookup(const char *name, const struct flag_type *flag_table) { int flag; for (flag = 0; flag_table[flag].name != NULL; flag++) { if (LOWER(name[0]) == LOWER(flag_table[flag].name[0]) && !str_cmp(name, flag_table[flag].name)) return flag_table[flag].bit; } return 0; } void mxp_support(DESCRIPTOR_DATA * d, int i, unsigned char *inbuf) { unsigned char *buf = &inbuf[i]; const char *supports; char arg[MIL]; const char *argument; static char tbuf[MSL]; int n = 10; flag_t bit; do { n++; } while (buf[n] != '>'); buf[n] = NUL; sprintf(tbuf, "%s", buf + 10); buf[n] = '>'; supports = str_dup(tbuf); n++; for (;;) { switch (buf[n]) { default: case NUL: break; case '\n': case '\r': n++; continue; break; } break; } telopt_lskip = n + 9; if (supports) { argument = supports; tbuf[0] = NUL; do { argument = one_argument(argument, arg); if (arg[0] != NUL) { if ((bit = mxp_lookup(arg + 1, mxp_support_flags)) > 0) { SET_BIT(d->mxp.flags, bit); } else if ((bit = mxp_lookup(arg + 1, mxp_support_flags2)) > 0) { SET_BIT(d->mxp.flags2, bit); } else sprintf(tbuf + strlen(tbuf), " %s", arg); } } while (arg[0] != NUL); free_string(supports); replace_string(d->mxp.supports, tbuf); } return; } void mxp_version(DESCRIPTOR_DATA * d, int i, unsigned char *inbuf) { unsigned char *buf = &inbuf[i]; char cbuf[MIL]; char rbuf[MIL]; char *arg; int n = 0; int c = 0; n = 0; cbuf[0] = NUL; rbuf[0] = NUL; do { buf[n] = UPPER(buf[n]); n++; } while (buf[n] != '>'); c = n; buf[c] = NUL; arg = (char *) &buf[5]; do { do { arg++; } while (*arg != ' ' && *arg != NUL); if (*arg == NUL) break; #define scan_arg(format1, format2, into) \ if(sscanf(arg, format2, into) != 1) \ sscanf(arg, format1, into); switch (UPPER(*(arg + 1))) { default: break; case 'C': scan_arg(" CLIENT=\"%s\"", " CLIENT=%s", cbuf); break; case 'M': scan_arg(" MXP=\"%f\"", " MXP=%f", &d->mxp.mxp_ver); break; case 'R': scan_arg(" REGISTERED=\"%s\"", " REGISTERED=%s", rbuf); break; case 'S': scan_arg(" STYLE=\"%f\"", " STYLE=%f", &d->mxp.style_ver); break; case 'V': scan_arg(" VERSION=\"%f\"", " VERSION=%f", &d->mxp.client_ver); break; } } while (*arg != NUL); replace_string(d->mxp.client, cbuf); d->mxp.registered = IS_NULLSTR(rbuf) ? 0 : (UPPER(rbuf[0]) == 'Y') ? 2 : 1; n = c + 1; buf[c] = '>'; for (;;) { switch (buf[n]) { default: case NUL: break; case '\n': case '\r': n++; continue; break; } break; } telopt_lskip = n - 1; if ((d->mxp.mxp_ver * 10) >= 4) { setup_mxp(d); } else REMOVE_BIT(d->d_flags, DESC_MXP); return; } void list_mxp_flags(CHAR_DATA * ch, DESCRIPTOR_DATA * d) { int flag; char *color; int max_col, col = 0; max_col = get_scr_cols(ch) / 13; for (flag = 0; mxp_support_flags[flag].name != NULL; flag++) { if (IS_SET(d->mxp.flags, mxp_support_flags[flag].bit)) color = "{G"; else color = "{r"; chprintf(ch, "|%s%s{x", color, stringf(ch, 12, ALIGN_CENTER, " ", mxp_support_flags[flag].name)); if (++col % max_col == 0) chprintln(ch, "|"); } for (flag = 0; mxp_support_flags2[flag].name != NULL; flag++) { if (IS_SET(d->mxp.flags, mxp_support_flags2[flag].bit)) color = "{G"; else color = "{r"; chprintf(ch, "|%s%s{x", color, stringf(ch, 12, ALIGN_CENTER, " ", mxp_support_flags2[flag].name)); if (++col % max_col == 0) chprintln(ch, "|"); } if (col % max_col != 0) chprintln(ch, "|"); return; } void mxp_details(CHAR_DATA * ch, DESCRIPTOR_DATA * d) { if (IS_SET(d->d_flags, DESC_MXP)) { chprintlnf(ch, "Status: {G%s{x", IS_MXP(d) ? "ON" : "OFF"); chprintlnf(ch, "Client: {G%s %1.2f %s{x", d->mxp.client, d->mxp.client_ver, d->mxp.registered == 1 ? "{D[{RUnregistered{D]" : d->mxp.registered == 2 ? "{D[{GRegistered{D]" : ""); chprintlnf(ch, "MXP Version: {Y%1.2f{x", d->mxp.mxp_ver); if (d->mxp.style_ver > 0) chprintlnf(ch, "Style Version: {M%1.2f{x", d->mxp.style_ver); if (!IS_NULLSTR(d->mxp.supports)) chprintlnf(ch, "MXP Info: %s", d->mxp.supports); chprintln(ch, draw_line(ch, NULL, 0)); if (d->mxp.flags || d->mxp.flags2) list_mxp_flags(ch, d); chprintln(ch, draw_line(ch, NULL, 0)); } return; } void send_portal(DESCRIPTOR_DATA * d, const char *format, ...) { char out[MSL]; char buf[MSL]; va_list args; int len; if (!IS_PORTAL(d) || IS_NULLSTR(format)) return; va_start(args, format); len = vsnprintf(buf, sizeof(buf), format, args); va_end(args); sprintf(out, "#K%%%05u%03d%s", d->portal.keycode, len, buf); d_write(d, out, 0); return; } void portal_sound(CHAR_DATA * ch, const char *sound) { send_portal(ch->desc, "%s%s", CL_SEND_SOUND, sound); return; } void portal_music(CHAR_DATA * ch, const char *sound, int iterations) { send_portal(ch->desc, "%s%s~%d", CL_SEND_MUSIC, sound, iterations); return; } void portal_image(CHAR_DATA * ch, const char *img) { send_portal(ch->desc, "%s%s~%s", CL_SEND_IMAGE, img, img); return; } void portal_map(CHAR_DATA * ch, ROOM_INDEX_DATA * pRoom) { int i; char buf[MSL]; bool found = FALSE; if (!IS_PORTAL(ch->desc) || !pRoom) return; buf[0] = NUL; for (i = 0; i < MAX_DIR; i++) { if (pRoom->exit[i] != NULL) { strcat(buf, " "); strcat(buf, &dir_name[i][0]); found = TRUE; } } if (found) send_portal(ch->desc, "%s%s", CL_SEND_ROOMCODE, buf + 1); } bool bust_a_portal(CHAR_DATA * ch) { static char buf[MSL]; char buf2[MSL]; DESCRIPTOR_DATA *d = ch->desc; CHAR_DATA *victim; // client is not portal client or no descriptor. if (!IS_PORTAL(d)) return FALSE; buf[0] = NUL; sprintf(buf2, "%s", CL_SEND_COMPOSITE); strcat(buf, buf2); sprintf(buf2, "%s%ld", CL_SEND_HP, ch->hit); strcat(buf, buf2); sprintf(buf2, "~%s%ld", CL_SEND_MAXHP, ch->max_hit); strcat(buf, buf2); sprintf(buf2, "~%s%ld", CL_SEND_SP, ch->mana); strcat(buf, buf2); sprintf(buf2, "~%s%ld", CL_SEND_MAXSP, ch->max_mana); strcat(buf, buf2); sprintf(buf2, "~%s%ld", CL_SEND_GP1, ch->move); strcat(buf, buf2); sprintf(buf2, "~%s%ld", CL_SEND_MAXGP1, ch->max_move); strcat(buf, buf2); victim = ch->fighting; if (victim && can_see(ch, victim)) { int percent; if (victim->max_hit > 0) percent = victim->hit * 100 / victim->max_hit; else percent = 0; sprintf(buf2, "~%s%s", CL_SEND_ATTACKER, victim->short_descr); strcat(buf, buf2); sprintf(buf2, "~%s%d", CL_SEND_ATTCOND, percent); strcat(buf, buf2); } else { sprintf(buf2, "~%s0", CL_SEND_ATTCOND); strcat(buf, buf2); } sprintf(buf2, "~%s<r[><sNext Level:> %d<sexp><r][><sPurse:> <y%ld> <sgold><r]>", CL_SEND_GLINE2, (ch->level + 1) * exp_per_level(ch, ch->pcdata-> points) - ch->exp, ch->gold); strcat(buf, buf2); sprintf(buf2, "~%s<r", CL_SEND_GLINE1); if (IS_SET(ch->comm, COMM_AFK)) { strcat(buf, "[><yAFK><r]"); } strcat(buf, ">"); strcat(buf, buf2); send_portal(d, buf); return TRUE; } CH_CMD(do_portal) { if (IS_NPC(ch) || !ch->desc) return; set_on_off(ch, &ch->desc->d_flags, DESC_PORTAL, "You now recieve portal enhancements.", "You no longer recieve portal enhancements."); } void send_imp(DESCRIPTOR_DATA * d, char *buf) { if (d == NULL) return; if (!IS_FIRECL(d)) return; d_write(d, buf, 0); return; } void imp_sound(CHAR_DATA * ch, const char *sound) { char buf[MSL]; sprintf(buf, "<AUDIO FILE=%s%s>", SOUND_URL, sound); send_imp(ch->desc, buf); return; } void imp_image(CHAR_DATA * ch, const char *img) { char buf[MSL]; sprintf(buf, "<IMG SRC=%s%s ALT=%s>", IMAGE_URL, img, img); send_imp(ch->desc, buf); return; } CH_CMD(do_imp) { if (IS_NPC(ch) || !ch->desc) return; set_on_off(ch, &ch->desc->d_flags, DESC_IMP, "Interactive Mudding Protocol on.", "Interactive Mudding Protocol off."); } CH_CMD(do_pueblo) { if (IS_NPC(ch) || !ch->desc) return; set_on_off(ch, &ch->desc->d_flags, DESC_PUEBLO, "You now recieve pueblo enhancements.", "You no longer recieve pueblo enhancements."); } void image_to_char(CHAR_DATA * ch, const char *image) { if (!ch || !image) return; if (IS_PUEBLO(ch->desc)) { chprint(ch, "</xch_mudtext><img xch_mode=html>"); chprintf(ch, "<img src=\"%s%s\">", IMAGE_URL, image); chprint(ch, "<br><br><img xch_mode=text>"); } else if (IS_PORTAL(ch->desc)) { portal_image(ch, image); } else if (IS_FIRECL(ch->desc)) imp_image(ch, image); else if (IS_MXP(ch->desc)) chprintf(ch, MXPTAG("IMAGE %s %s"), image, IMAGE_URL); } CH_CMD(do_msp) { if (IS_NPC(ch) || !ch->desc) return; set_on_off(ch, &ch->desc->d_flags, DESC_MSP, "MUD Sound Protocol on.", "MUD Sound Protocol off."); } void send_sound(CHAR_DATA * ch, const char *sfile, int prio) { if (!ch || IS_NPC(ch) || IS_NULLSTR(sfile)) return; if (IS_MXP(ch->desc)) chprintf(ch, MXPTAG("SOUND %s 100 1 %d %s"), sfile, prio, SOUND_URL); else if (IS_MSP(ch->desc)) chprintf(ch, "!!SOUND( %s V=100 p=%d U=%s)", sfile, prio, SOUND_URL); else if (IS_PUEBLO(ch->desc)) chprintf(ch, "</xch_mudtext><img xch_mode=html>" "<img xch_sound=play xch_volume=100 src=\"%s%s\">" "<br><img xch_mode=text>", SOUND_URL, sfile); else if (IS_PORTAL(ch->desc)) portal_sound(ch, sfile); else if (IS_FIRECL(ch->desc)) imp_sound(ch, sfile); return; } void sound_to_room(ROOM_INDEX_DATA * room, const char *sfile, int prio) { CHAR_DATA *rch; if (room == NULL || IS_NULLSTR(sfile)) return; for (rch = room->first_person; rch != NULL; rch = rch->next_in_room) { if (IS_NPC(rch) || rch->desc == NULL) continue; send_sound(rch, sfile, prio); } return; } void sound_to_area(AREA_DATA * area, const char *sfile, int prio) { DESCRIPTOR_DATA *d; if (area == NULL || IS_NULLSTR(sfile)) return; for (d = descriptor_first; d != NULL; d = d->next) { if (d->connected != CON_PLAYING) continue; if (d->character != NULL && d->character->in_room != NULL && d->character->in_room->area == area) send_sound(d->character, sfile, prio); } return; } void sound_to_world(const char *sfile, int prio) { DESCRIPTOR_DATA *d; if (IS_NULLSTR(sfile)) return; for (d = descriptor_first; d != NULL; d = d->next) { if (d->connected != CON_PLAYING) continue; send_sound(d->character, sfile, prio); } return; } void send_music(CHAR_DATA * ch, const char *url, const char *sound) { if (!ch || IS_NPC(ch) || !sound) return; if (IS_MXP(ch->desc)) chprintf(ch, MXPTAG("MUSIC %s V=100 L=-1 U=%s"), sound, SOUND_URL); else if (IS_MSP(ch->desc)) chprintf(ch, "!!MUSIC(%s V=100 L=-1 U=%s)", sound, SOUND_URL); else if (IS_PUEBLO(ch->desc)) chprintf(ch, "</xch_mudtext><img xch_mode=html>" "<img xch_sound=loop xch_volume=100 src=\"%s%s\">" "<br><img xch_mode=text>", SOUND_URL, sound); else if (IS_PORTAL(ch->desc)) portal_music(ch, sound, 1); else if (IS_FIRECL(ch->desc)) imp_sound(ch, sound); } void music_to_room(ROOM_INDEX_DATA * room, const char *url, const char *sound) { CHAR_DATA *rch; if (room == NULL || IS_NULLSTR(sound)) return; for (rch = room->first_person; rch != NULL; rch = rch->next_in_room) { if (IS_NPC(rch) || rch->desc == NULL) continue; send_music(rch, url, sound); } return; } void music_to_area(AREA_DATA * area, const char *url, const char *sound) { DESCRIPTOR_DATA *d; CHAR_DATA *ch; if (area == NULL || IS_NULLSTR(sound)) return; for (d = descriptor_first; d != NULL; d = d->next) { if (d->connected != CON_PLAYING) continue; if ((ch = CH(d)) != NULL && ch->in_room != NULL && ch->in_room->area == area) send_music(ch, url, sound); } return; } void music_to_world(const char *url, const char *sound) { DESCRIPTOR_DATA *d; if (IS_NULLSTR(sound)) return; for (d = descriptor_first; d != NULL; d = d->next) { if (d->connected != CON_PLAYING) continue; send_music(CH(d), url, sound); } return; }