static void DrawEyes( CImage& img, // io const vec_Rect& leyes, // in const vec_Rect& reyes, // in int ileft_best, // in int iright_best, // in const Rect& facerect, // in EYAW eyaw) // in { // rectangles showing search regions const int linewidth = facerect.width > 700? 3: facerect.width > 300? 2: 1; const Rect left_rect(EyeSearchRect(eyaw, facerect, false)); const Rect right_rect(EyeSearchRect(eyaw, facerect, true)); const Rect eye_inner_rect(EyeInnerRect(eyaw, facerect)); DrawRect(img, facerect, Dark(C_YELLOW), linewidth); DrawRect(img, left_rect, VeryDark(C_RED), linewidth); DrawRect(img, right_rect, VeryDark(C_GREEN), linewidth); DrawRect(img, eye_inner_rect, Dark(C_YELLOW), linewidth); int i; for (i = 0; i < NSIZE(leyes); i++) DrawFeat(img, i, leyes, C_RED, linewidth, i==ileft_best); for (i = 0; i < NSIZE(reyes); i++) DrawFeat(img, i, reyes, C_RED /*C_GREEN*/, linewidth, i==iright_best); }
bool can_see(dbref player, dbref thing, bool can_see_loc) { if (!OkObj(player) || !OkObj(thing)) return 0; if (player == thing || Typeof(thing) == TYPE_EXIT || Typeof(thing) == TYPE_ROOM) return 0; if (Light(thing)) return 1; if (can_see_loc) { switch (Typeof(thing)) { case TYPE_PROGRAM: return ((FLAGS(thing) & LINK_OK) || controls(player, thing) || (POWERS(player) & POW_SEE_ALL)); case TYPE_PLAYER: if (tp_dark_sleepers) { return (!Dark(thing) || online(thing) || (POWERS(player) & POW_SEE_ALL)); } default: return (!Dark(thing) || (POWERS(player) & POW_SEE_ALL) || (controls(player, thing) && !(FLAGS(player) & STICKY))); } } else { /* can't see loc */ return (controls(player, thing) && !(FLAGS(player) & STICKY)); } }
/* Show the 'Obvious Exits' list for a room. Used in 'look' and 'examine'. * \param player The player looking * \param loc room whose exits we're showing * \param exit_name "Obvious Exits" string * \param pe_info the pe_info to use for evaluating EXITFORMAT and interact locks */ static void look_exits(dbref player, dbref loc, const char *exit_name, NEW_PE_INFO *pe_info) { dbref thing; char *tbuf1, *tbuf2, *nbuf; char *s1, *s2; char *p; int exit_count, this_exit, total_count; int texits; ufun_attrib ufun; PUEBLOBUFF; /* make sure location is a room */ if (!IsRoom(loc)) return; tbuf1 = (char *) mush_malloc(BUFFER_LEN, "string"); tbuf2 = (char *) mush_malloc(BUFFER_LEN, "string"); nbuf = (char *) mush_malloc(BUFFER_LEN, "string"); if (!tbuf1 || !tbuf2 || !nbuf) mush_panic("Unable to allocate memory in look_exits"); s1 = tbuf1; s2 = tbuf2; texits = exit_count = total_count = 0; this_exit = 1; if (fetch_ufun_attrib ("EXITFORMAT", loc, &ufun, UFUN_IGNORE_PERMS | UFUN_REQUIRE_ATTR)) { char *arg, *buff, *bp; PE_REGS *pe_regs = pe_regs_create(PE_REGS_ARG, "look_exits"); arg = (char *) mush_malloc(BUFFER_LEN, "string"); buff = (char *) mush_malloc(BUFFER_LEN, "string"); if (!arg || !buff) mush_panic("Unable to allocate memory in look_exits"); bp = arg; DOLIST(thing, Exits(loc)) { if (((Light(loc) || Light(thing)) || !(Dark(loc) || Dark(thing))) && can_interact(thing, player, INTERACT_SEE, pe_info)) { if (bp != arg) safe_chr(' ', arg, &bp); safe_dbref(thing, arg, &bp); } } *bp = '\0'; pe_regs_setenv_nocopy(pe_regs, 0, arg); call_ufun(&ufun, buff, player, player, pe_info, pe_regs); pe_regs_free(pe_regs); notify_by(loc, player, buff); mush_free(tbuf1, "string"); mush_free(tbuf2, "string"); mush_free(nbuf, "string"); mush_free(arg, "string"); mush_free(buff, "string"); return; }
/* * --------------------------------------------------------------------------- * * process_enter_loc: Generate messages and actions resulting from entering * * a place. */ static void process_enter_loc(dbref thing, dbref src, dbref cause, int canhear, int hush) { dbref loc; int quiet, pattr, oattr, aattr; loc = Location(thing); if((loc == NOTHING) || (loc == src)) return; /* * Run the ENTER attributes in the current room if we meet any of * * * * * * * following criteria: * - The current room has wizard privs. * * - * * * Neither the current room nor the moving object are dark. * * - The * * * moving object can hear and does not hav wizard * privs. * EXCEPT * if * * we were called with the HUSH_ENTER key. */ quiet = (!(Wizard(loc) || (!Dark(thing) && !Dark(loc)) || (canhear && !(Wizard(thing) && Dark (thing))))) || (hush & HUSH_ENTER); oattr = quiet ? 0 : A_OENTER; aattr = quiet ? 0 : A_AENTER; pattr = (!mudconf.terse_movemsg && Terse(thing)) ? 0 : A_ENTER; did_it(thing, loc, pattr, NULL, oattr, NULL, aattr, (char **) NULL, 0); /* * Do OXLEAVE for sending room */ if((src != NOTHING) && !quiet) did_it(thing, src, 0, NULL, A_OXLEAVE, NULL, 0, (char **) NULL, 0); /* * Display the 'has arrived' message if we meet all of the following * * * * * criteria: * - The moving object can hear. * - The object * is * * not * a dark wizard. */ if(!quiet && canhear && !(Dark(thing) && Wizard(thing))) { notify_except2(loc, thing, thing, cause, tprintf("%s has arrived.", Name(thing))); } }
/** Return the first object near another object that is visible to a player. * * BEWARE: * * first_visible() does not behave as intended. It _should_ return the first * object in `thing' that is !DARK. However, because of the controls() check * the function will return a DARK object if the player owns it. * * The behavior is left as is because so many functions in fundb.c rely on * the incorrect behavior to return expected values. The lv*() functions * also make rewriting this fairly pointless. * * \param player the looker. * \param thing an object in the location to be inspected. * \return dbref of first visible object or NOTHING. */ dbref first_visible(dbref player, dbref thing) { int lck = 0; int ldark; dbref loc; if (!GoodObject(thing) || IsRoom(thing)) return NOTHING; loc = IsExit(thing) ? Source(thing) : Location(thing); if (!GoodObject(loc)) return NOTHING; ldark = IsPlayer(loc) ? Opaque(loc) : Dark(loc); while (GoodObject(thing)) { if (can_interact(thing, player, INTERACT_SEE, NULL)) { if (DarkLegal(thing) || (ldark && !Light(thing))) { if (!lck) { if (See_All(player) || (loc == player) || controls(player, loc)) return thing; lck = 1; } if (controls(player, thing)) /* this is what causes DARK objects to show */ return thing; } else { return thing; } } thing = Next(thing); } return thing; }
void AColor::TrackPanelBackground(wxDC * dc, bool selected) { #ifdef EXPERIMENTAL_THEMING UseThemeColour( dc, selected ? clrDarkSelected : clrDark); #else Dark( dc, selected ); #endif }
static bool match_exit_internal(dbref loc, dbref baseloc, int local) { if ( !Good_obj(loc) || !Has_exits(loc)) { return true; } dbref exit; bool result = false; int key; DOLIST(exit, Exits(loc)) { if (exit == md.absolute_form) { key = 0; if (Examinable(md.player, loc)) { key |= VE_LOC_XAM; } if (Dark(loc)) { key |= VE_LOC_DARK; } if (Dark(baseloc)) { key |= VE_BASE_DARK; } if (exit_visible(exit, md.player, key)) { promote_match(exit, CON_DBREF | local); return true; } } if (matches_exit_from_list(md.string, PureName(exit))) { promote_match(exit, CON_COMPLETE | local); result = true; } } return result; }
bool can_doit(int descr, dbref player, dbref thing, const char *default_fail_msg) { dbref loc; if ((loc = getloc(player)) == NOTHING) return 0; if (OkObj(thing)) { dbref dest = Typeof(thing) == TYPE_EXIT ? (DBFETCH(thing)->sp.exit.ndest ? DBFETCH(thing)->sp.exit.dest[0] : NOTHING) : NOTHING; if (((FLAG2(player) & F2IMMOBILE) && !(FLAG2(thing) & F2IMMOBILE)) && (!OkObj(dest) || Typeof(dest) != TYPE_PROGRAM) ) { envpropqueue(descr, player, OkObj(player) ? getloc(player) : -1, thing, thing, NOTHING, "@immobile", "Immobile", 1, 1); return 0; } } if (!TMage(OWNER(player)) && Typeof(player) == TYPE_THING && (FLAGS(thing) & ZOMBIE)) { notify(player, "Sorry, but zombies can't do that."); return 0; } if (!could_doit(descr, player, thing)) { /* can't do it */ if (GETFAIL(thing)) { exec_or_notify(descr, player, thing, GETFAIL(thing), "(@Fail)"); } else if (default_fail_msg) { notify(player, default_fail_msg); } if (GETOFAIL(thing) && !Dark(player)) { parse_omessage(descr, player, loc, thing, GETOFAIL(thing), PNAME(player), "(@Ofail)"); } return 0; } else { /* can do it */ /* I moved these to the 'trigger()' function. -Akari */ /* if (GETSUCC(thing)) { exec_or_notify(descr, player, thing, GETSUCC(thing), "(@Succ)"); } if (GETOSUCC(thing) && !Dark(player)) { parse_omessage(descr, player, loc, thing, GETOSUCC(thing), NAME(player), "(@Osucc)"); } */ return 1; } }
int can_doit(int descr, dbref player, dbref thing, const char *default_fail_msg) { dbref loc; if ((loc = getloc(player)) == NOTHING) return 0; if (!Wizard(OWNER(player)) && Typeof(player) == TYPE_THING && (FLAGS(thing) & ZOMBIE)) { notify(player, "Sorry, but zombies can't do that."); return 0; } if (!could_doit(descr, player, thing)) { /* can't do it */ if (GETFAIL(thing)) { exec_or_notify_prop(descr, player, thing, MESGPROP_FAIL, "(@Fail)"); } else if (default_fail_msg) { notify(player, default_fail_msg); } if (GETOFAIL(thing) && !Dark(player)) { parse_oprop(descr, player, loc, thing, MESGPROP_OFAIL, NAME(player), "(@Ofail)"); } return 0; } else { /* can do it */ if (GETSUCC(thing)) { exec_or_notify_prop(descr, player, thing, MESGPROP_SUCC, "(@Succ)"); } if (GETOSUCC(thing) && !Dark(player)) { parse_oprop(descr, player, loc, thing, MESGPROP_OSUCC, NAME(player), "(@Osucc)"); } return 1; } }
static void DrawMouths( CImage& img, // io const vec_Rect& mouths, // in int ibest, // in const Rect& facerect, // in EYAW eyaw, // in int ileft_best, // in: index of best left eye, -1 if none int iright_best, // in: index of best right eye, -1 if none const vec_Rect& leyes, // in: left eyes found by eye detector const vec_Rect& reyes) // in: right eyes found by eye detector { const int linewidth = facerect.width > 700? 3: facerect.width > 300? 2: 1; const Rect mouth_searchrect( MouthSearchRect(facerect, eyaw, ileft_best, iright_best, leyes, reyes)); const Rect inner_rect( MouthInnerRect(facerect, eyaw, ileft_best, iright_best, leyes, reyes)); DrawRect(img, facerect, Dark(C_YELLOW), 3 * linewidth); DrawRect(img, mouth_searchrect, VeryDark(C_YELLOW), linewidth); DrawRect(img, inner_rect, Dark(C_YELLOW), linewidth); int i; for (i = 0; i < NSIZE(mouths); i++) DrawFeat(img, i, mouths, C_RED, linewidth, i==ibest); }
static void process_leave_loc(dbref thing, dbref dest, dbref cause, int canhear, int hush) { dbref loc; int quiet, pattr, oattr, aattr; loc = Location(thing); if((loc == NOTHING) || (loc == dest)) return; if(dest == HOME) dest = Home(thing); /* * Run the LEAVE attributes in the current room if we meet any of * * * * * * * following criteria: * - The current room has wizard privs. * * - * * * Neither the current room nor the moving object are dark. * * - The * * * moving object can hear and does not hav wizard * privs. * EXCEPT * if * * we were called with the HUSH_LEAVE key. */ quiet = (!(Wizard(loc) || (!Dark(thing) && !Dark(loc)) || (canhear && !(Wizard(thing) && Dark (thing))))) || (hush & HUSH_LEAVE); oattr = quiet ? 0 : A_OLEAVE; aattr = quiet ? 0 : A_ALEAVE; pattr = (!mudconf.terse_movemsg && Terse(thing)) ? 0 : A_LEAVE; did_it(thing, loc, pattr, NULL, oattr, NULL, aattr, (char **) NULL, 0); /* * Do OXENTER for receiving room */ if((dest != NOTHING) && !quiet) did_it(thing, dest, 0, NULL, A_OXENTER, NULL, 0, (char **) NULL, 0); /* * Display the 'has left' message if we meet any of the following * * * * * * * criteria: * - Neither the current room nor the moving * object are * * * dark. * - The object can hear and is not a dark * wizard. */ if(!quiet) if((!Dark(thing) && !Dark(loc)) || (canhear && !(Wizard(thing) && Dark(thing)))) { notify_except2(loc, thing, thing, cause, tprintf("%s has left.", Name(thing))); } }
static void DrawFeat( // draw eye (or mouth) at index i in the eyes vec CImage& img, // io int i, // in const vec_Rect& eyes, // in unsigned col, // in int linewidth, // in bool best) // in: true if this is the best eye { double x, y; RectToImgFrame(x, y, eyes[i]); Rect rect; rect.x = cvRound(x - eyes[i].width / 2); rect.y = cvRound(y - eyes[i].height / 2); rect.width = eyes[i].width; rect.height = eyes[i].height; if (!best) col = Dark(col); DrawRect(img, rect, col, linewidth); cv::circle(img, cv::Point(cvRound(x), cvRound(y)), (best? 2: 1) * linewidth, ToCvColor(col), linewidth); }
void CGuiTabWnd::Drawtabs(CDC* dc) { CPen light(PS_SOLID,1,GetSysColor(COLOR_BTNHIGHLIGHT)); CPen Dark(PS_SOLID,1,GetSysColor(COLOR_BTNSHADOW)); CPen Black(PS_SOLID,1,GetSysColor(BLACK_PEN)); CRect rectText; CFont* m_fontOld=dc->SelectObject(&m_cfont); for (int iCont=0; iCont< m_Numtabs;iCont++) { CGuiTab* ct=(CGuiTab*) m_pArray[iCont]; CPen* oldPen= dc->SelectObject(&light); //si es la carpeta seleccionada, se debe //eliminar las lineas oscuras de encima if (iCont ==m_iSelectTab) { CBrush cbr; CRect m_rectTabAux=ct->rect; m_rectTabAux.DeflateRect(1,1); m_rectTabAux.top-=4; m_rectTabAux.bottom=m_rectTabAux.top+4; cbr.CreateSysColorBrush(COLOR_BTNFACE); dc->FillRect(ct->rect,&cbr); dc->MoveTo(ct->rect.left,ct->rect.top-3); dc->LineTo(ct->rect.left,ct->rect.bottom-1); dc->FillRect(m_rectTabAux,&cbr); dc->SelectStockObject(BLACK_PEN); dc->MoveTo(ct->rect.left,ct->rect.bottom-1); dc->LineTo(ct->rect.right,ct->rect.bottom-1); //linea derecha observe que se pinta dos veces para //dar el efecto de redondeada en la puntas dc->SelectStockObject(BLACK_PEN); dc->MoveTo(ct->rect.right-1,ct->rect.top-1); dc->LineTo(ct->rect.right-1,ct->rect.bottom-1); } else { if ((iCont+1) != m_iSelectTab) { dc->SelectObject(&Dark); dc->MoveTo(ct->rect.right-1,ct->rect.top+2); dc->LineTo(ct->rect.right-1,ct->rect.bottom-2); } } //se dibuja el icono int nMode = dc->SetBkMode(TRANSPARENT); CSize m_sChar=dc->GetTextExtent(ct->lpMsg,strlen(ct->lpMsg)); if (m_sizeImag.cx+m_sChar.cx < ct->rect.Width()-8) { Image.Draw(dc,ct->uIcon,CPoint(ct->rect.left+2,ct->rect.top+2),ILD_TRANSPARENT); rectText=ct->rect; rectText.left+=m_sizeImag.cx+8; rectText.right-=2; dc->DrawText(ct->lpMsg,rectText,DT_SINGLELINE|DT_LEFT|DT_VCENTER); CToolTip.SetToolRect(this,iCont+1,CRect(0,0,0,0)); } else { //verificamos si se puede poner algun texto o //por lo memos el icono if (m_sizeImag.cx < ct->rect.Width()) { Image.Draw(dc,ct->uIcon,CPoint(ct->rect.left+2,ct->rect.top+2),ILD_TRANSPARENT); rectText=ct->rect; rectText.left+=m_sizeImag.cx+8; rectText.right-=5; CString m_cadBreak=ct->lpMsg; int c=0; int cont=m_cadBreak.GetLength(); while(cont > 1 ) { CString m_scadtemp=m_cadBreak+"..."; CSize coor=dc->GetTextExtent(m_scadtemp,m_scadtemp.GetLength()); if(coor.cx > rectText.Width()) m_cadBreak=m_cadBreak.Left(m_cadBreak.GetLength()-1); else break; cont--; } m_cadBreak+=_T("..."); rectText.right+=3; dc->DrawText(m_cadBreak,rectText,DT_SINGLELINE|DT_LEFT|DT_VCENTER); CToolTip.SetToolRect(this,iCont+1,&ct->rect); } } dc->SetBkMode(nMode); // Modified By SunZhenyu dc->SelectObject(oldPen); } dc->SelectObject(m_fontOld); }
static void ct_exit(dbref player, dbref i, warn_type flags) { dbref j, src, dst; int count = 0; int lt; /* i must be an exit, must be in a valid room, and must lead to a * different room * Remember, for exit i, Exits(i) = source room * and Location(i) = destination room */ dst = Destination(i); if ((flags & W_EXIT_UNLINKED) && (dst == NOTHING)) complain(player, i, "exit-unlinked", T("exit is unlinked; anyone can steal it")); if ((flags & W_EXIT_UNLINKED) && dst == AMBIGUOUS) { ATTR *a; const char *var = "DESTINATION"; a = atr_get(i, "DESTINATION"); if (!a) a = atr_get(i, "EXITTO"); if (a) var = "EXITTO"; if (!a) complain(player, i, "exit-unlinked", T("Variable exit has no %s attribute"), var); else { const char *x = atr_value(a); if (!x || !*x) complain(player, i, "exit-unlinked", T("Variable exit has empty %s attribute"), var); } } if (!Dark(i)) { if (flags & W_EXIT_MSGS) { lt = warning_lock_type(getlock(i, Basic_Lock)); if ((lt & W_UNLOCKED) && (!atr_get(i, "OSUCCESS") || !atr_get(i, "ODROP") || !atr_get(i, "SUCCESS"))) complain(player, i, "exit-msgs", T("possibly unlocked exit missing succ/osucc/odrop")); if ((lt & W_LOCKED) && !atr_get(i, "FAILURE")) complain(player, i, "exit-msgs", T("possibly locked exit missing fail")); } if (flags & W_EXIT_DESC) { if (!atr_get(i, "DESCRIBE")) complain(player, i, "exit-desc", T("exit is missing description")); } } src = Source(i); if (!GoodObject(src) || !IsRoom(src)) return; if (src == dst) return; /* Don't complain about exits linked to HOME or variable exits. */ if (!GoodObject(dst)) return; for (j = Exits(dst); GoodObject(j); j = Next(j)) if (Location(j) == src) { if (!(flags & W_EXIT_MULTIPLE)) return; else count++; } if ((count == 0) && (flags & W_EXIT_ONEWAY)) complain(player, i, "exit-oneway", T("exit has no return exit")); else if ((count > 1) && (flags & W_EXIT_MULTIPLE)) complain(player, i, "exit-multiple", T("exit has multiple (%d) return exits"), count); }
void CGuiMiniFrame::OnNcPaint() { CGuiControlBar* pBar=(CGuiControlBar* )GetChildWnd(); if (!pBar) return; if (IsGuiControlBar==TRUE && !pBar->IsAutoHide()) { CMiniDockFrameWnd::OnNcPaint(); return; } //if (!pBar->GetComplete()) return; CRect rcWindow; CRect rcClient; CWindowDC dc(this); CDC m_dc; //contexto de dispositivo en memoria CBitmap m_bitmap; CPen Dark(PS_SOLID,1,GuiDrawLayer::GetRGBColorShadow(GuiDrawLayer::m_Style)); //la idea es tomar el area de la ventana y area cliente , luego debemos //igualar el area de coordenadas de ventana al cliente GetWindowRect(&rcWindow); GetClientRect(&rcClient); int nSize=rcClient.right; ScreenToClient(rcWindow); rcClient.OffsetRect(-rcWindow.TopLeft()); rcWindow.OffsetRect(-rcWindow.TopLeft()); m_dc.CreateCompatibleDC(&dc); m_bitmap.CreateCompatibleBitmap(&dc,rcWindow.Width(),rcWindow.Height()); CBitmap *m_OldBitmap=m_dc.SelectObject(&m_bitmap); //aqui debe utilizarse la brocha que define GuiDrawLayer, si no hacemos la siguiente //linea usted vera un horrible color negro, a cambio del dibujo. CBrush cb; COLORREF clrBrush; if(IsGuiControlBar!=TRUE ) clrBrush= GuiDrawLayer::GetRGBColorShadow(GuiDrawLayer::m_Style); else clrBrush=GuiDrawLayer::GetRGBColorFace(GuiDrawLayer::m_Style); cb.CreateSolidBrush(clrBrush); m_dc.FillRect(rcWindow, &cb); if (IsGuiControlBar==TRUE && pBar->IsAutoHide()) { CRect m_rc=rcWindow; if (pBar->GetLastDocking() == CBRS_ALIGN_LEFT) { m_rc.left=m_rc.right-1; m_rc.top+=3; cb.DeleteObject(); cb.CreateSolidBrush(RGB(0,0,0)); } if (pBar->GetLastDocking() == CBRS_ALIGN_RIGHT) { m_rc.right=m_rc.left+1; m_rc.top+=2; cb.DeleteObject(); cb.CreateSolidBrush(GuiDrawLayer::GetRGBColorBTNHigh()); } if (pBar->GetLastDocking() == CBRS_ALIGN_TOP) { m_rc.top=m_rc.bottom-1; cb.DeleteObject(); cb.CreateSolidBrush(RGB(0,0,0)); } m_dc.FillRect(m_rc, &cb); } CRect rcCaption=rcClient; rcCaption.InflateRect(1,1); if(IsGuiControlBar!=TRUE ) dc.Draw3dRect(rcCaption,GuiDrawLayer::GetRGBColorBTNHigh(),GuiDrawLayer::GetRGBColorBTNHigh()); DrawGripper(&m_dc,&rcClient); dc.IntersectClipRect(rcWindow); dc.ExcludeClipRect(rcClient);//asi evitamos el parpadeo //rcWindow.InflateRect(1,1); dc.BitBlt(rcWindow.left,rcWindow.top,rcWindow.Width(),rcWindow.Height(),&m_dc,0,0,SRCCOPY); ReleaseDC(&dc); m_dc.SelectObject(m_OldBitmap); m_bitmap.DeleteObject(); m_dc.DeleteDC(); // SetTimer(1,200,NULL); // TODO: Add your message handler code here // Do not call CMiniDockFrameWnd::OnNcPaint() for painting messages }
/** The whisper command. * \param player the enactor. * \param arg1 name of the object to whisper to. * \param arg2 message to whisper. * \param noisy if 1, others overhear that a whisper has occurred. * \param pe_info the pe_info for evaluating interact locks */ void do_whisper(dbref player, const char *arg1, const char *arg2, int noisy, NEW_PE_INFO *pe_info) { dbref who; int key; const char *gap; char *tbuf, *tp; char *p; dbref good[100]; int gcount = 0; const char *head; int overheard; char *current; const char **start; char sname[BUFFER_LEN]; if (!arg1 || !*arg1) { notify(player, T("Whisper to whom?")); return; } if (!arg2 || !*arg2) { notify(player, T("Whisper what?")); return; } tp = tbuf = (char *) mush_malloc(BUFFER_LEN, "string"); if (!tbuf) mush_panic("Unable to allocate memory in do_whisper"); overheard = 0; head = arg1; start = &head; /* Figure out what kind of message */ gap = " "; switch (*arg2) { case SEMI_POSE_TOKEN: gap = ""; case POSE_TOKEN: key = 1; arg2++; break; default: key = 2; break; } *tp = '\0'; /* Make up a list of good and bad names */ while (head && *head) { current = next_in_list(start); who = match_result(player, current, TYPE_PLAYER, MAT_NEAR_THINGS | MAT_CONTAINER); if (!GoodObject(who) || !can_interact(player, who, INTERACT_HEAR, pe_info)) { safe_chr(' ', tbuf, &tp); safe_str_space(current, tbuf, &tp); if (GoodObject(who)) notify_format(player, T("%s can't hear you."), AName(who, AN_SYS, NULL)); } else { /* A good whisper */ good[gcount++] = who; if (gcount >= 100) { notify(player, T("Too many people to whisper to.")); break; } } } *tp = '\0'; if (*tbuf) notify_format(player, T("Unable to whisper to:%s"), tbuf); if (!gcount) { mush_free(tbuf, "string"); return; } /* Drunk wizards... */ if (Dark(player)) noisy = 0; /* Set up list of good names */ tp = tbuf; safe_str(T(" to "), tbuf, &tp); for (who = 0; who < gcount; who++) { if (noisy && (get_random32(0, 100) < (uint32_t) WHISPER_LOUDNESS)) overheard = 1; safe_itemizer(who + 1, (who == gcount - 1), ",", T("and"), " ", tbuf, &tp); safe_str(AName(good[who], AN_SAY, NULL), tbuf, &tp); } *tp = '\0'; if (key == 1) { notify_format(player, (gcount > 1) ? T("%s sense: %s%s%s") : T("%s senses: %s%s%s"), tbuf + 4, AName(player, AN_SAY, NULL), gap, arg2); p = tprintf("You sense: %s%s%s", AName(player, AN_SAY, NULL), gap, arg2); } else { notify_format(player, T("You whisper, \"%s\"%s."), arg2, tbuf); p = tprintf(T("%s whispers%s: %s"), AName(player, AN_SAY, NULL), gcount > 1 ? tbuf : "", arg2); } strcpy(sname, AName(player, AN_SAY, NULL)); for (who = 0; who < gcount; who++) { notify_must_puppet(good[who], p); if (Location(good[who]) != Location(player)) overheard = 0; } if (overheard) { dbref first = Contents(Location(player)); if (!GoodObject(first)) return; p = tprintf(T("%s whispers%s."), sname, tbuf); DOLIST(first, first) { overheard = 1; for (who = 0; who < gcount; who++) { if ((first == player) || (first == good[who])) { overheard = 0; break; } } if (overheard) notify_noecho(first, p); } }