/* * UserStartDrag: User wants to drag object under mouse pointer. If there is no * object there, do nothing. If there is more than one object, ask user which * one to pick up. If there is exactly one, begin dragging object. */ void UserStartDrag(void) { list_type objects, sel_list, l; int x, y; object_node *obj; /* Find out where in the the room the user clicked on, if anywhere */ if (!MouseToRoom(&x, &y)) return; objects = GetObjects3D(x, y, CLOSE_DISTANCE, OF_GETTABLE | OF_CONTAINER, 0); if (objects == NULL) return; if (objects->next == NULL) { SetCapture(hMain); capture = True; obj = (object_node *) objects->data; drag_object = obj->id; SetMainCursor(LoadCursor(hInst, MAKEINTRESOURCE(IDC_GETCURSOR))); } else { sel_list = DisplayLookList(hMain, GetString(hInst, IDS_GET), objects, LD_SINGLEAUTO); for (l = sel_list; l != NULL; l = l->next) RequestPickup(((room_contents_node *) (l->data))->obj.id); ObjectListDestroy(sel_list); } list_delete(objects); }
/* * DescDialogProc: Dialog procedure for dialog containing an * item's long description. */ BOOL CALLBACK DescDialogProc(HWND hDlg, UINT message, UINT wParam, LONG lParam) { DescDialogStruct *info; static HWND hwndBitmap; static Bool changed; // True when player has changed description HWND hEdit, hwndOK, hURL, hFixed; HDC hdc; HFONT hFont; RECT dlg_rect, edit_rect, fixed_rect; AREA area; char *desc, *str, url[MAX_URL + 1], *pPageBreak; DRAWITEMSTRUCT *lpdis; char descriptionBuffer[MAX_PAGE_DESCRIPTION_TEXT+1]; int height; info = (DescDialogStruct *) GetWindowLong(hDlg, DWL_USER); switch (message) { case WM_INITDIALOG: info = (DescDialogStruct *) lParam; /* Store structure in dialog box's extra bytes */ SetWindowLong(hDlg, DWL_USER, (long) info); hwndBitmap = GetDlgItem(hDlg, IDC_DESCBITMAP); hFixed = GetDlgItem(hDlg, IDC_DESCFIXED); hEdit = GetDlgItem(hDlg, IDC_DESCBOX); hwndOK = GetDlgItem(hDlg, IDOK); // Item Name. height = SetFontToFitText(info,GetDlgItem(hDlg, IDC_DESCNAME), (int)FONT_TITLES, info->name); SetDlgItemText(hDlg, IDC_DESCNAME, info->name); hdc = GetDC(hDlg); SetTextColor(hdc,GetPlayerNameColor(info->obj,info->name)); ReleaseDC(hDlg,hdc); // Item Description. hFont = GetFont(FONT_EDIT); SetWindowFont(hFixed, hFont, FALSE); SetWindowFont(hEdit, hFont, FALSE); str = info->description; if (str) { pPageBreak = strchr(str,PAGE_BREAK_CHAR); while (pPageBreak) { info->numPages++; str = pPageBreak+1; pPageBreak = strchr(str,PAGE_BREAK_CHAR); } info->numPages++; GetPageText(descriptionBuffer,info); Edit_SetText(hEdit, descriptionBuffer); } // Show fixed string, if appropriate if (info->fixed_string != NULL) { SetDlgItemText(hDlg, IDC_DESCFIXED, info->fixed_string); SetWindowFont(GetDlgItem(hDlg, IDC_DESCFIXED), GetFont(FONT_EDIT), FALSE); } // Can this player edit this object's description? if (info->flags & DF_EDITABLE) Edit_SetReadOnly(hEdit, FALSE); Edit_LimitText(hEdit, MAX_DESCRIPTION); if (!(info->flags & (DF_EDITABLE | DF_INSCRIBED)) && !str) { GetWindowRect(hFixed, &fixed_rect); GetWindowRect(hEdit, &edit_rect); UnionRect(&fixed_rect, &fixed_rect, &edit_rect); ScreenToClient(hDlg, (LPPOINT)(&fixed_rect)); ScreenToClient(hDlg, (LPPOINT)(&fixed_rect)+1); MoveWindow(hFixed, fixed_rect.left, fixed_rect.top, fixed_rect.right - fixed_rect.left, fixed_rect.bottom - fixed_rect.top, FALSE); ShowWindow(hEdit, SW_HIDE); } // Resize and move dialog controls GetWindowRect(hDlg, &dlg_rect); if (GetWindowLong(hEdit, GWL_STYLE) & WS_VISIBLE) { ShowWindow(hEdit, SW_HIDE); ResizeEditToFitText(hFixed, hFont); ResizeDialog(hDlg, &dlg_rect, desc_controls); ShowWindow(hEdit, SW_SHOW); } else { ResizeEditToFitText(hFixed, hFont); ResizeDialog(hDlg, &dlg_rect, desc_controls); } if (GetWindowLong(hEdit, GWL_STYLE) & WS_VISIBLE) { GetWindowRect(hFixed, &fixed_rect); GetWindowRect(hEdit, &edit_rect); height = fixed_rect.bottom-edit_rect.top; ScreenToClient(hDlg, (LPPOINT)(&edit_rect)); ScreenToClient(hDlg, (LPPOINT)(&edit_rect)+1); ShowWindow(hFixed, SW_HIDE); OffsetRect(&edit_rect, 0, height); MoveWindow(hEdit, edit_rect.left, edit_rect.top, edit_rect.right - edit_rect.left, edit_rect.bottom - edit_rect.top, FALSE); GetWindowRect(hDlg, &dlg_rect); ResizeEditToFitText(hEdit, hFont); ResizeDialog(hDlg, &dlg_rect, desc_controls); ShowWindow(hFixed, SW_SHOW); } CenterWindow(hDlg, GetParent(hDlg)); // Show URL, if appropriate if (info->url != NULL) { hURL = GetDlgItem(hDlg, IDC_URL); SetWindowText(hURL, info->url); SetWindowFont(hURL, GetFont(FONT_EDIT), FALSE); if (info->flags & DF_EDITABLE) Edit_SetReadOnly(hURL, FALSE); Edit_LimitText(hURL, MAX_URL); } // Show appropriate buttons if (!(desc_flags & DESC_GET)) DestroyWindow(GetDlgItem(hDlg, IDC_GET)); if (!(desc_flags & DESC_DROP)) DestroyWindow(GetDlgItem(hDlg, IDC_DROP)); if (!(desc_flags & DESC_USE)) DestroyWindow(GetDlgItem(hDlg, IDC_USE)); if (!(desc_flags & DESC_UNUSE)) DestroyWindow(GetDlgItem(hDlg, IDC_UNUSE)); if (!(desc_flags & DESC_INSIDE)) DestroyWindow(GetDlgItem(hDlg, IDC_INSIDE)); if (!(desc_flags & DESC_ACTIVATE)) DestroyWindow(GetDlgItem(hDlg, IDC_ACTIVATE)); if (!(desc_flags & DESC_APPLY)) DestroyWindow(GetDlgItem(hDlg, IDC_APPLY)); SetLookPageButtons(hDlg, info); #if 0 if (info->numPages < 2) { HWND hwnd = GetDlgItem(hDlg,IDC_NEXT); if (hwnd) DestroyWindow(GetDlgItem(hDlg, IDC_NEXT)); hwnd = GetDlgItem(hDlg,IDC_PREV); if (hwnd) DestroyWindow(GetDlgItem(hDlg, IDC_PREV)); } else { HWND hwnd = GetDlgItem(hDlg,IDC_PREV); if (hwnd) EnableWindow(hwnd,FALSE); } #endif SetFocus(hwndOK); hDescDialog = hDlg; changed = False; return FALSE; case WM_PAINT: InvalidateRect(hwndBitmap, NULL, TRUE); UpdateWindow(hwndBitmap); /* fall through */ case BK_ANIMATE: /* Draw object's bitmap */ hdc = GetDC(hwndBitmap); GetClientRect(hwndBitmap, &dlg_rect); RectToArea(&dlg_rect, &area); DrawStretchedObjectGroup(hdc, info->obj, info->obj->animate->group, &area, GetSysColorBrush(COLOR_3DFACE)); ReleaseDC(hwndBitmap, hdc); break; HANDLE_MSG(hDlg, WM_CTLCOLOREDIT, DialogCtlColor); HANDLE_MSG(hDlg, WM_CTLCOLORLISTBOX, DialogCtlColor); HANDLE_MSG(hDlg, WM_CTLCOLORSTATIC, DialogCtlColor); HANDLE_MSG(hDlg, WM_CTLCOLORDLG, DialogCtlColor); case WM_DESTROY: hDescDialog = NULL; return TRUE; case WM_DRAWITEM: // Draw player name in color that reflects murderer status lpdis = (DRAWITEMSTRUCT *) lParam; switch (lpdis->itemAction) { case ODA_SELECT: case ODA_DRAWENTIRE: SelectPalette(lpdis->hDC, hPal, FALSE); hFont = info->hFontTitle; SelectObject(lpdis->hDC, hFont); SetBkMode(lpdis->hDC, TRANSPARENT); str = LookupNameRsc(info->obj->name_res); SetTextColor(lpdis->hDC, NAME_COLOR_NORMAL_BG); DrawText(lpdis->hDC, str, strlen(str), &lpdis->rcItem, DT_LEFT | DT_VCENTER | DT_NOPREFIX); OffsetRect(&lpdis->rcItem, -1, -1); SetTextColor(lpdis->hDC, GetPlayerNameColor(info->obj, info->name)); DrawText(lpdis->hDC, str, strlen(str), &lpdis->rcItem, DT_LEFT | DT_VCENTER | DT_NOPREFIX); break; } return TRUE; case WM_COMMAND: switch(GET_WM_COMMAND_ID(wParam, lParam)) { case IDC_PREV: if (info->currentPage > 0) info->currentPage--; GetPageText(descriptionBuffer,info); SetLookPageButtons(hDlg, info); Edit_SetText(GetDlgItem(hDlg, IDC_DESCBOX), descriptionBuffer); #if 0 EnableWindow(GetDlgItem(hDlg,IDC_PREV),info->currentPage > 0); EnableWindow(GetDlgItem(hDlg,IDC_NEXT),info->currentPage < info->numPages-1); #endif return TRUE; case IDC_NEXT: if (info->currentPage < info->numPages-1) info->currentPage++; GetPageText(descriptionBuffer,info); Edit_SetText(GetDlgItem(hDlg, IDC_DESCBOX), descriptionBuffer); SetLookPageButtons(hDlg, info); #if 0 EnableWindow(GetDlgItem(hDlg,IDC_PREV),info->currentPage > 0); EnableWindow(GetDlgItem(hDlg,IDC_NEXT),info->currentPage < info->numPages-1); #endif return TRUE; case IDC_GET: RequestPickup(info->obj->id); EndDialog(hDlg, 0); return TRUE; case IDC_DROP: // Drop all of number items info->obj->temp_amount = info->obj->amount; RequestDrop(info->obj); EndDialog(hDlg, 0); return TRUE; case IDC_USE: // If player isn't holding the object (i.e. there's a Get button), pick object up first if (IsWindowVisible(GetDlgItem(hDlg, IDC_GET))) RequestPickup(info->obj->id); RequestUse(info->obj->id); EndDialog(hDlg, 0); return TRUE; case IDC_UNUSE: RequestUnuse(info->obj->id); EndDialog(hDlg, 0); return TRUE; case IDC_INSIDE: RequestObjectContents(info->obj->id); EndDialog(hDlg, 0); return TRUE; case IDC_ACTIVATE: RequestActivate(info->obj->id); EndDialog(hDlg, 0); return TRUE; case IDC_APPLY: StartApply(info->obj->id); EndDialog(hDlg, 0); return TRUE; case IDC_DESCBOX: if (GET_WM_COMMAND_CMD(wParam, lParam) != EN_CHANGE) break; changed = True; return TRUE; case IDC_URLBUTTON: hURL = GetDlgItem(hDlg, IDC_URL); Edit_GetText(hURL, url, MAX_URL); WebLaunchBrowser(url); return TRUE; case IDOK: // Send new description if changed if (changed) { desc = (char *) SafeMalloc(MAX_DESCRIPTION + 1); GetDlgItemText(hDlg, IDC_DESCBOX, desc, MAX_DESCRIPTION); RequestChangeDescription(info->obj->id, desc); SafeFree(desc); } // Send new URL if changed if (info->url != NULL) { GetDlgItemText(hDlg, IDC_URL, url, MAX_URL); if (strcmp(url, info->url)) RequestChangeURL(player.id, url); } // FALLTHRU case IDCANCEL: SetWindowFont(GetDlgItem(hDlg,IDC_DESCNAME), GetFont(FONT_TITLES), FALSE); if (info->hFontTitle && info->hFontTitle != GetFont(FONT_TITLES)) DeleteObject(info->hFontTitle); info->hFontTitle = NULL; EndDialog(hDlg, IDOK == GET_WM_COMMAND_ID(wParam, lParam)); return TRUE; } break; } return FALSE; }
/* * InterfaceAction: User wants to perform given action. Return True iff * action should be passed along for further processing. */ Bool InterfaceAction(int action, void *action_data) { POINT mouse; AREA a; room_contents_node *r; static int lastRestWarning = 0; if ((pinfo.resting || cinfo->effects->paralyzed) && (IsMoveAction(action) || IsAttackAction(action))) { // debug(("Can't do while resting\n")); return False; } switch (action) { case A_TARGETCLEAR: case A_TARGETSELF: case A_TARGETNEXT: case A_TARGETPREVIOUS: case A_ATTACK: UserAreaRedraw(); return True; break; case A_FORWARDFAST: // If too tired, don't run if (pinfo.vigor < MIN_VIGOR) { PerformAction(A_FORWARD, NULL); return False; } break; case A_BACKWARDFAST: if (pinfo.vigor < MIN_VIGOR) { PerformAction(A_BACKWARD, NULL); return False; } break; case A_SLIDELEFTFAST: if (pinfo.vigor < MIN_VIGOR) { PerformAction(A_SLIDELEFT, NULL); return False; } break; case A_SLIDERIGHTFAST: if (pinfo.vigor < MIN_VIGOR) { PerformAction(A_SLIDERIGHT, NULL); return False; } break; case A_SLIDELEFTFORWARDFAST: if (pinfo.vigor < MIN_VIGOR) { PerformAction(A_SLIDELEFTFORWARD, NULL); return False; } break; case A_SLIDELEFTBACKWARDFAST: if (pinfo.vigor < MIN_VIGOR) { PerformAction(A_SLIDELEFTBACKWARD, NULL); return False; } break; case A_SLIDERIGHTFORWARDFAST: if (pinfo.vigor < MIN_VIGOR) { PerformAction(A_SLIDERIGHTFORWARD, NULL); return False; } break; case A_SLIDERIGHTBACKWARDFAST: if (pinfo.vigor < MIN_VIGOR) { PerformAction(A_SLIDERIGHTBACKWARD, NULL); return False; } break; case A_CAST: UserCastSpell(); return False; case A_CASTSPELL: // action_data is pointer to spell if (GetPlayer()->viewID && (GetPlayer()->viewID != GetPlayer()->id)) { if (!(GetPlayer()->viewFlags & REMOTE_VIEW_CAST)) { GameMessage(GetString(hInst, IDS_SPELLPARALYZED)); return False; } } if (cinfo->effects->paralyzed) { GameMessage(GetString(hInst, IDS_SPELLPARALYZED)); return False; } if (pinfo.resting) { GameMessage(GetString(hInst, IDS_SPELLRESTING)); return False; } SpellCast((spell *) action_data); return False; case A_GO: if (pinfo.resting) return False; break; case A_ENDDRAG: // action_data is ID of object being dragged // See if user dragged object to inventory InventoryGetArea(&a); GetCursorPos(&mouse); ScreenToClient(cinfo->hMain, &mouse); if (!IsInArea(&a, mouse.x, mouse.y)) break; r = GetRoomObjectById((ID) action_data); if (r == NULL) break; // If a non-gettable container, try to get contents if ((r->obj.flags & OF_CONTAINER) && !(r->obj.flags & OF_GETTABLE)) RequestObjectContents((ID) action_data); else RequestPickup((ID) action_data); break; case A_TABFWD: return InterfaceTab((int) action_data, True); case A_TABBACK: return InterfaceTab((int) action_data, False); } return True; }