/* * 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) seperate 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; }