/* * Descent 3 * Copyright (C) 2024 Parallax Software * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . --- HISTORICAL COMMENTS FOLLOW --- * $Logfile: /DescentIII/Main/editor/DoorwayDialog.cpp $ * $Revision: 1.1.1.1 $ * $Date: 2003-08-26 03:57:37 $ * $Author: kevinb $ * * Doorway keypad * * $Log: not supported by cvs2svn $ * * 23 5/05/99 2:02a Matt * Added doorway flag to tell the Guide-Bot to ignore the locked state of * the door. * * 22 4/03/99 7:55p Matt * Use new keypad update system instead of timer to update. * * 21 3/05/99 1:51p Kevin * Fixed small crash bug * * 20 3/01/99 10:37a Matt * Update doorway tab when the door object is renamed * * 19 2/06/99 10:03p Matt * Added keys system * * 18 2/04/99 2:05p Matt * Added blastable doors * * 17 1/29/99 12:48p Matt * Rewrote the doorway system * * 16 9/22/98 12:02p Matt * Fixed compile warnings * * 15 9/08/98 12:06p Jason * added automatic reinitting of doors when rooms get deleted * * 14 9/02/98 4:32p Matt * Added some error checking when placing a door. * * 13 6/15/98 4:00p Jason * replaced monochromatic polymodel lighting with rgb lighting * * 12 4/20/98 2:52p Jason * added doorway reinit function * * 11 4/07/98 11:05a Kevin * For Samir, added m_Active to the if statement in the timer interrupt * * 10 4/02/98 3:54p Jason * first pass in getting polymodel paging to work * * 9 12/19/97 11:25a Samir * g3_StartFrame and g3_EndFrame replaced by EditorStartFrame and * EditorEndFrame * * 8 10/03/97 12:24p Jason * added new keys for doorways * * 7 9/29/97 12:09p Jason * added functionality to doorway system * * 6 9/23/97 12:29p Jason * fixed m_Active bug * * 5 9/17/97 1:01p Matt * Ripped out segment code * * 4 9/11/97 5:46p Jason * first pass at getting doors to work with room engine * * 3 7/24/97 6:11p Matt * Created symbolic constant for default zoom, and used it every place * that specifies zoom * * 20 6/03/97 4:55p Mark * * 20 6/03/97 4:51p Jeff * Added Context Sensitive Help * * 19 4/02/97 5:15p Samir * Added a Opened checkbox to mark a door as open or closed initially * * 18 4/01/97 11:00p Matt * Changed editor to keep a viewer object (type camera) separate from the * player object. This camera, and not the player, is now moved by * slewing, the C key, etc. When going into the game, the viewer position * & orientation are copied to the player. When going back to the editor, * the player position is copied to the viewer, and the player object is * reset to its start location. * * 17 3/31/97 5:57p Matt * Revamped mine update flags * * 16 3/26/97 5:43p Samir * Fixed refresh of doorway selector when changing state of door page. * * 15 3/25/97 6:31p Samir * Now you can select from different 3d doors hopefully. * * 14 3/24/97 6:47p Samir * Fixed some place,remove doorway probs with 3d doors. Made some state * vars static for multiple instances of dialog. * * 13 3/20/97 12:10p Samir * Fixed prob when going into fullscreen with doorway keypad visible. * * 12 3/19/97 7:02p Samir * If adding door segment fails, don't register it as a door! And * deactivated moving doorways from one seg to another for now. * * 11 3/18/97 11:35a Samir * Fixed user interface problems. * * $NoKeywords: $ */ // DoorwayDialog.cpp : implementation file // #include "stdafx.h" #include "editor.h" #include "DoorwayDialog.h" #include "door.h" #include "HView.h" #include "HRoom.h" #include "polymodel.h" #include "edoors.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif int Current_door_room = -1; ///////////////////////////////////////////////////////////////////////////// // CDoorwayDialog dialog CDoorwayDialog::CDoorwayDialog(CWnd *pParent /*=NULL*/) : CKeypadDialog(CDoorwayDialog::IDD, pParent) { //{{AFX_DATA_INIT(CDoorwayDialog) // NOTE: the ClassWizard will add member initialization here //}}AFX_DATA_INIT // m_SelectionType = DOORWAY_DOOR; } void CDoorwayDialog::DoDataExchange(CDataExchange *pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CDoorwayDialog) // NOTE: the ClassWizard will add DDX and DDV calls here //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CDoorwayDialog, CDialog) //{{AFX_MSG_MAP(CDoorwayDialog) ON_WM_VSCROLL() ON_WM_HSCROLL() ON_WM_SIZE() ON_WM_PAINT() ON_BN_CLICKED(IDC_DOORWAY_PLACEDOOR, OnDoorwayPlaceDoorway) ON_BN_CLICKED(IDC_NEXT_DOOR, OnNextDoor) ON_BN_CLICKED(IDC_PREV_DOOR, OnPrevDoor) ON_BN_CLICKED(IDC_DOORWAY_LOCKED, OnDoorwayLocked) ON_BN_CLICKED(IDC_KEY1_CHECK, OnKey1Check) ON_BN_CLICKED(IDC_KEY2_CHECK, OnKey2Check) ON_BN_CLICKED(IDC_KEY3_CHECK, OnKey3Check) ON_BN_CLICKED(IDC_KEY4_CHECK, OnKey4Check) ON_BN_CLICKED(IDC_KEY5_CHECK, OnKey5Check) ON_BN_CLICKED(IDC_KEY6_CHECK, OnKey6Check) ON_BN_CLICKED(IDC_KEY7_CHECK, OnKey7Check) ON_BN_CLICKED(IDC_KEY8_CHECK, OnKey8Check) ON_BN_CLICKED(IDC_DOORWAY_ATTACHDOOR, OnDoorwayAttachDoor) ON_BN_CLICKED(IDC_DOORWAY_AUTO, OnDoorwayAuto) ON_EN_KILLFOCUS(IDC_DOORWAY_POS_EDIT, OnKillfocusDoorwayPosEdit) ON_EN_KILLFOCUS(IDC_DOORWAY_HITPOINT_EDIT, OnKillfocusDoorwayHitpointEdit) ON_BN_CLICKED(IDC_DOORWAY_KEY_ALL, OnDoorwayKeyAll) ON_BN_CLICKED(IDC_DOORWAY_KEY_ONLY_ONE, OnDoorwayKeyOnlyOne) ON_BN_CLICKED(IDC_DOORWAY_GB_IGNORE_LOCKED, OnDoorwayGBIgnoreLocked) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CDoorwayDialog message handlers void CDoorwayDialog::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar *pScrollBar) { // TODO: Add your message handler code here and/or call default CKeypadDialog::OnVScroll(nSBCode, nPos, pScrollBar); } void CDoorwayDialog::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar *pScrollBar) { // TODO: Add your message handler code here and/or call default CKeypadDialog::OnHScroll(nSBCode, nPos, pScrollBar); } void CDoorwayDialog::OnSize(UINT nType, int cx, int cy) { CKeypadDialog::OnSize(nType, cx, cy); } void CDoorwayDialog::OnPaint() { CPaintDC dc(this); // device context for painting UpdateDialog(); } BOOL CDoorwayDialog::OnInitDialog() { CDialog::OnInitDialog(); UpdateDialog(); return TRUE; } void CDoorwayDialog::OnOK() { CWnd *focus = CWnd::GetFocus(); if (focus) focus->GetNextWindow()->SetFocus(); } void CDoorwayDialog::EnableCurrentItems(bool state) { ((CButton *)GetDlgItem(IDC_DOORWAY_ID))->EnableWindow(state); ((CButton *)GetDlgItem(IDC_DOORWAY_LOCKED))->EnableWindow(state); ((CButton *)GetDlgItem(IDC_DOORWAY_GB_IGNORE_LOCKED))->EnableWindow(state); ((CButton *)GetDlgItem(IDC_DOORWAY_AUTO))->EnableWindow(state); ((CButton *)GetDlgItem(IDC_DOORWAY_CURRENT_BOX))->EnableWindow(state); ((CButton *)GetDlgItem(IDC_DOORWAY_POS_TEXT))->EnableWindow(state); ((CButton *)GetDlgItem(IDC_DOORWAY_POS_EDIT))->EnableWindow(state); ((CButton *)GetDlgItem(IDC_DOORWAY_HITPOINT_TEXT))->EnableWindow(state); ((CButton *)GetDlgItem(IDC_DOORWAY_HITPOINT_EDIT))->EnableWindow(state); ((CButton *)GetDlgItem(IDC_DOORWAY_KEYS_TEXT))->EnableWindow(state); ((CButton *)GetDlgItem(IDC_DOORWAY_KEY_ALL))->EnableWindow(state); ((CButton *)GetDlgItem(IDC_DOORWAY_KEY_ONLY_ONE))->EnableWindow(state); ((CButton *)GetDlgItem(IDC_KEY1_CHECK))->EnableWindow(state); ((CButton *)GetDlgItem(IDC_KEY2_CHECK))->EnableWindow(state); ((CButton *)GetDlgItem(IDC_KEY3_CHECK))->EnableWindow(state); ((CButton *)GetDlgItem(IDC_KEY4_CHECK))->EnableWindow(state); ((CButton *)GetDlgItem(IDC_KEY5_CHECK))->EnableWindow(state); ((CButton *)GetDlgItem(IDC_KEY6_CHECK))->EnableWindow(state); ((CButton *)GetDlgItem(IDC_KEY7_CHECK))->EnableWindow(state); ((CButton *)GetDlgItem(IDC_KEY8_CHECK))->EnableWindow(state); } // --------------------------------------------------------------------------- // Update doorway key functions functions // --------------------------------------------------------------------------- char last_name[OBJ_NAME_LEN + 1]; void CDoorwayDialog::UpdateDialog() { if (!m_Active) return; if (Num_doors <= 0) return; if (Doors[D3EditState.current_door].used == 0) D3EditState.current_door = GetNextDoor(D3EditState.current_door); int door_handle = D3EditState.current_door; CEdit *ebox = (CEdit *)GetDlgItem(IDC_DOORWAYSELEDIT); ebox->SetWindowText(Doors[door_handle].name); DrawDoorwayDoorPic(); ((CButton *)GetDlgItem(IDC_DOORWAY_ATTACHDOOR))->EnableWindow(Placed_door != -1); ebox = (CEdit *)GetDlgItem(IDC_DOORWAY_ID); if (Cur_object_index == -1 || Objects[Cur_object_index].type != OBJ_DOOR) { ebox->SetWindowText("No doorway selected"); Current_door_room = -1; EnableCurrentItems(0); } else { char str[250]; object *objp = &Objects[Cur_object_index]; EnableCurrentItems(1); Current_door_room = objp->roomnum; ASSERT(Rooms[Current_door_room].flags & RF_DOOR); strcpy(last_name, Objects[Cur_object_index].name ? Objects[Cur_object_index].name : ""); sprintf(str, "Door: %s ", last_name); ebox->SetWindowText(str); doorway *dw = Rooms[Current_door_room].doorway_data; sprintf(str, "%.2f", dw->position); ebox = (CEdit *)GetDlgItem(IDC_DOORWAY_POS_EDIT); ebox->SetWindowText(str); // Update key check boxes CButton *bbox = (CButton *)GetDlgItem(IDC_DOORWAY_LOCKED); bbox->SetCheck(dw->flags & DF_LOCKED); bbox = (CButton *)GetDlgItem(IDC_DOORWAY_AUTO); bbox->SetCheck(dw->flags & DF_AUTO); bbox = (CButton *)GetDlgItem(IDC_DOORWAY_GB_IGNORE_LOCKED); bbox->SetCheck(dw->flags & DF_GB_IGNORE_LOCKED); bbox = (CButton *)GetDlgItem(IDC_KEY1_CHECK); bbox->SetCheck(dw->keys_needed & KEY_FLAG(1)); bbox = (CButton *)GetDlgItem(IDC_KEY2_CHECK); bbox->SetCheck(dw->keys_needed & KEY_FLAG(2)); bbox = (CButton *)GetDlgItem(IDC_KEY3_CHECK); bbox->SetCheck(dw->keys_needed & KEY_FLAG(3)); bbox = (CButton *)GetDlgItem(IDC_KEY4_CHECK); bbox->SetCheck(dw->keys_needed & KEY_FLAG(4)); bbox = (CButton *)GetDlgItem(IDC_KEY5_CHECK); bbox->SetCheck(dw->keys_needed & KEY_FLAG(5)); bbox = (CButton *)GetDlgItem(IDC_KEY6_CHECK); bbox->SetCheck(dw->keys_needed & KEY_FLAG(6)); bbox = (CButton *)GetDlgItem(IDC_KEY7_CHECK); bbox->SetCheck(dw->keys_needed & KEY_FLAG(7)); bbox = (CButton *)GetDlgItem(IDC_KEY8_CHECK); bbox->SetCheck(dw->keys_needed & KEY_FLAG(8)); // Update key radio buttons bbox = (CButton *)GetDlgItem(IDC_DOORWAY_KEY_ALL); bbox->SetCheck(!(dw->flags & DF_KEY_ONLY_ONE)); bbox = (CButton *)GetDlgItem(IDC_DOORWAY_KEY_ONLY_ONE); bbox->SetCheck(dw->flags & DF_KEY_ONLY_ONE); // Update hitpoints editing door *door = &Doors[dw->doornum]; bool blastable = ((door->flags & DF_BLASTABLE) != 0); ((CButton *)GetDlgItem(IDC_DOORWAY_HITPOINT_TEXT))->EnableWindow(blastable); sprintf(str, "%d", (int)objp->shields); ebox = (CEdit *)GetDlgItem(IDC_DOORWAY_HITPOINT_EDIT); ebox->SetWindowText(str); ebox->EnableWindow(blastable); } } // update doorway picture void CDoorwayDialog::DrawDoorwayDoorPic() { int door_handle = D3EditState.current_door; vector zero_vector; vector view_vector = {0, 0, -20}; matrix id_matrix; float norm_angles[30]; int w, h, bm_handle, x, y; RECT rect; CWnd *wnd = GetDlgItem(IDC_DOORPIC); Desktop_surf->attach_to_window((unsigned)wnd->m_hWnd); wnd->GetWindowRect(&rect); ScreenToClient(&rect); w = rect.right - rect.left; h = rect.bottom - rect.top; m_DoorSurf.create(w, h, BPP_16); Desktop_surf->clear(0, 0, w, h); bm_handle = GetDoorImage(door_handle); poly_model *pm = GetPolymodelPointer(bm_handle); vm_MakeZero(&zero_vector); vm_MakeIdentity(&id_matrix); for (int i = 0; i < 30; i++) norm_angles[i] = 0; grViewport *vport = new grViewport(&m_DoorSurf); StartEditorFrame(vport, &view_vector, &id_matrix, D3_DEFAULT_ZOOM); DrawPolygonModel(&zero_vector, &id_matrix, bm_handle, norm_angles, 0, 1.0, 1.0, 1.0); EndEditorFrame(); x = rect.left + ((rect.right - rect.left) / 2) - m_DoorSurf.width() / 2; y = rect.top + ((rect.bottom - rect.top) / 2) - m_DoorSurf.height() / 2; Desktop_surf->blt(0, 0, &m_DoorSurf); delete vport; m_DoorSurf.free(); Desktop_surf->attach_to_window((unsigned)NULL); } // --------------------------------------------------------------------------- // Doorway editing functions // --------------------------------------------------------------------------- void CDoorwayDialog::OnDoorwayPlaceDoorway() { if (Num_doors <= 0) return; if (D3EditState.current_door == -1) { OutrageMessageBox("You must have a current door for this operation"); return; } if (Curroomp->faces[Curface].portal_num != -1) { OutrageMessageBox("There's already a connection at the current room:face."); return; } PlaceDoor(Curroomp, Curface, D3EditState.current_door); UpdateDialog(); World_changed = 1; } /*BOOL CDoorwayDialog::OnHelpInfo(HELPINFO* pHelpInfo) { // TODO: Add your message handler code here and/or call default WinHelp(HID_DOORWAYTAB,HELP_CONTEXT); return TRUE; //return CDialog::OnHelpInfo(pHelpInfo); }*/ void CDoorwayDialog::OnNextDoor() { if (Num_doors <= 0) return; D3EditState.current_door = GetNextDoor(D3EditState.current_door); UpdateDialog(); } void CDoorwayDialog::OnPrevDoor() { if (Num_doors <= 0) return; D3EditState.current_door = GetPrevDoor(D3EditState.current_door); UpdateDialog(); } void CDoorwayDialog::OnDoorwayLocked() { if (Current_door_room == -1) return; doorway *dp = Rooms[Current_door_room].doorway_data; ASSERT(dp != NULL); int c = IsDlgButtonChecked(IDC_DOORWAY_LOCKED); if (c) dp->flags |= DF_LOCKED; else dp->flags &= ~DF_LOCKED; } void CDoorwayDialog::UpdateKeypad(int mask) { if (mask & (KUF_CUROBJ_CHANGED + KUF_CUROBJ_NAME_CHANGED)) UpdateDialog(); } void CDoorwayDialog::OnKeyCheck(int id, int keynum) { if (Current_door_room == -1) return; doorway *dp = Rooms[Current_door_room].doorway_data; ASSERT(dp != NULL); if (IsDlgButtonChecked(id)) dp->keys_needed |= KEY_FLAG(keynum); else dp->keys_needed &= ~KEY_FLAG(keynum); } void CDoorwayDialog::OnKey1Check() { OnKeyCheck(IDC_KEY1_CHECK, 1); } void CDoorwayDialog::OnKey2Check() { OnKeyCheck(IDC_KEY2_CHECK, 2); } void CDoorwayDialog::OnKey3Check() { OnKeyCheck(IDC_KEY3_CHECK, 3); } void CDoorwayDialog::OnKey4Check() { OnKeyCheck(IDC_KEY4_CHECK, 4); } void CDoorwayDialog::OnKey5Check() { OnKeyCheck(IDC_KEY5_CHECK, 5); } void CDoorwayDialog::OnKey6Check() { OnKeyCheck(IDC_KEY6_CHECK, 6); } void CDoorwayDialog::OnKey7Check() { OnKeyCheck(IDC_KEY7_CHECK, 7); } void CDoorwayDialog::OnKey8Check() { OnKeyCheck(IDC_KEY8_CHECK, 8); } void CDoorwayDialog::OnDoorwayAttachDoor() { ASSERT(Placed_door != -1); AttachRoom(); UpdateDialog(); } void CDoorwayDialog::OnDoorwayAuto() { if (Current_door_room == -1) return; doorway *dp = Rooms[Current_door_room].doorway_data; ASSERT(dp != NULL); int c = IsDlgButtonChecked(IDC_DOORWAY_AUTO); if (c) dp->flags |= DF_AUTO; else dp->flags &= ~DF_AUTO; } void CDoorwayDialog::OnKillfocusDoorwayPosEdit() { if (Current_door_room == -1) return; doorway *dp = Rooms[Current_door_room].doorway_data; ASSERT(dp != NULL); char str[100]; CEdit *ebox = (CEdit *)GetDlgItem(IDC_DOORWAY_POS_EDIT); ebox->GetWindowText(str, sizeof(str)); dp->position = dp->dest_pos = atof(str); if (dp->position < 0.0) dp->position = 0.0; if (dp->position > 1.0) dp->position = 1.0; dp->dest_pos = dp->position; DoorwayUpdateAnimation(&Rooms[Current_door_room]); World_changed = 1; } void CDoorwayDialog::OnKillfocusDoorwayHitpointEdit() { if (Current_door_room == -1) return; doorway *dp = Rooms[Current_door_room].doorway_data; ASSERT(dp != NULL); char str[100]; CEdit *ebox = (CEdit *)GetDlgItem(IDC_DOORWAY_HITPOINT_EDIT); ebox->GetWindowText(str, sizeof(str)); ASSERT(Objects[Cur_object_index].type == OBJ_DOOR); Objects[Cur_object_index].shields = atof(str); World_changed = 1; } void CDoorwayDialog::OnDoorwayKeyAll() { if (Current_door_room == -1) return; doorway *dp = Rooms[Current_door_room].doorway_data; ASSERT(dp != NULL); if (IsDlgButtonChecked(IDC_DOORWAY_KEY_ALL)) dp->flags &= ~DF_KEY_ONLY_ONE; else dp->flags |= DF_KEY_ONLY_ONE; World_changed = 1; UpdateDialog(); } void CDoorwayDialog::OnDoorwayKeyOnlyOne() { if (Current_door_room == -1) return; doorway *dp = Rooms[Current_door_room].doorway_data; ASSERT(dp != NULL); if (IsDlgButtonChecked(IDC_DOORWAY_KEY_ONLY_ONE)) dp->flags |= DF_KEY_ONLY_ONE; else dp->flags &= ~DF_KEY_ONLY_ONE; World_changed = 1; UpdateDialog(); } void CDoorwayDialog::OnDoorwayGBIgnoreLocked() { if (Current_door_room == -1) return; doorway *dp = Rooms[Current_door_room].doorway_data; ASSERT(dp != NULL); int c = IsDlgButtonChecked(IDC_DOORWAY_GB_IGNORE_LOCKED); if (c) dp->flags |= DF_GB_IGNORE_LOCKED; else dp->flags &= ~DF_GB_IGNORE_LOCKED; }