// InstanceWindow.cpp : implementation file // #include "stdafx.h" #include "MW4GameEd.h" #include "EditorChildWnd.h" #include #include #include #include #include "MoveCommand.h" #include "AddCommand.h" #include #include #include #include #include #include #include #include #include "InstanceWindow.h" #include "GenericTextDlg.h" #include "transDlg.h" #include "DeleteCommand.h" #include #include "EditorWaypoint.h" #include "GenericListDlg.h" #include #include #include #include #include #include "LatticeLinkDlg.h" #include #include "LightWnd.h" #include "AblMemDlg.h" #include "DisplayWindow.h" #include "OverviewWindow.h" #include "Selection.h" #include "editskilldlg.hpp" #include #define __mbschr(s,c) (char*)_mbschr((const unsigned char*)(s),(c)) #define __mbsrchr(s,c) (char*)_mbsrchr((const unsigned char*)(s),(c)) Entity* CallbackEntity = NULL; extern CMW4GameEdApp theApp; bool InstanceEditScriptCallback(char* filename) { if (CallbackEntity) { ABL::ABLError err; MWObject *obj; obj = Cast_Object (MWObject *,CallbackEntity); // should not fail since you should not be able to attach an ai to a non mwobject if (!obj->m_AI->LoadScript(filename)) { char errString[256]; sprintf(errString,"%s on Line %d.",err.String(),err.Line()); MessageBox(NULL,errString,"ABL Error",MB_OK); return false; } } return true; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // CInstanceWindow IMPLEMENT_DYNCREATE(CInstanceWindow, CEditorChildWnd) CInstanceWindow::CInstanceWindow() : mechList(NULL), buildingList(NULL), vehicleList(NULL), miscList(NULL) { CString title; RECT rect; TLDlg = NULL; scriptWnd = NULL; title.LoadString(IDS_INSTANCEWINDOWTITLE); rect.top = 410; rect.left = 650; rect.bottom = 600; rect.right = 900; Create(NULL,title,WS_CHILD | WS_CLIPSIBLINGS | WS_OVERLAPPEDWINDOW | WS_VISIBLE,rect);//,theApp.m_pMainWnd,0); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // CInstanceWindow::~CInstanceWindow() { ClearInstanceLists(); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // BEGIN_MESSAGE_MAP(CInstanceWindow,CEditorChildWnd) //{{AFX_MSG_MAP(CInstanceWindow) ON_WM_CREATE() ON_WM_SIZE() ON_WM_RBUTTONDOWN() ON_COMMAND(ID_OBJ_NAME, OnObjName) ON_COMMAND(ID_OBJ_PARAMETERS, OnObjParameters) ON_COMMAND(ID_OBJ_TRANSLATION, OnObjTranslation) ON_COMMAND(ID_OBJ_REMOVEINSTANCE, OnObjRemoveinstance) ON_COMMAND(ID_OBJ_GOTOINSTANCE, OnObjGotoinstance) ON_COMMAND(ID_OBJ_DAMAGEOBJARMOR, OnObjDamageobjArmor) ON_COMMAND(ID_OBJ_DAMAGEOBJINTERNAL, OnObjDamageobjInternal) ON_COMMAND(ID_OBJ_EDITDRIVER, OnObjEditDriver) ON_COMMAND(ID_OBJ_SPECIFYSCRIPT, OnObjSpecifyScript) ON_COMMAND(ID_OBJ_EDITSCRIPT, OnObjEditScript) ON_COMMAND(ID_OBJ_CLEARAI, OnClearAI) ON_COMMAND(ID_OBJ_EDITOBJECTIVE, OnObjEditObjective) ON_WM_LBUTTONUP() ON_WM_LBUTTONDBLCLK() ON_COMMAND(ID_OBJ_ALIGNMENT, OnObjAlignment) ON_COMMAND(ID_EDITLIGHT, OnEditLight) ON_COMMAND(ID_OBJ_ABLMEMORY, OnABLMemory) ON_COMMAND(ID_OBJ_EDITSKILL, OnEditSkill) //}}AFX_MSG_MAP END_MESSAGE_MAP() //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // CInstanceWindow message handlers int CInstanceWindow::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CEditorChildWnd::OnCreate(lpCreateStruct) == -1) return -1; TLDlg = new CObjWindow; TLDlg->Create(CObjWindow::IDD,this); RECT r; memset(&r,0,sizeof(r)); TLDlg->m_ObjList.Create(WS_CHILD | WS_VISIBLE | LBS_EXTENDEDSEL | LBS_NOINTEGRALHEIGHT | LBS_STANDARD,r,TLDlg,0); TLDlg->m_TabCtrl.InsertItem(0,TLDlg->mechTab); TLDlg->m_TabCtrl.InsertItem(1,TLDlg->buildingTab); TLDlg->m_TabCtrl.InsertItem(2,TLDlg->vehicleTab); TLDlg->m_TabCtrl.InsertItem(3,TLDlg->miscTab); ((CButton*)(TLDlg->GetDlgItem(IDC_INSTANCETYPEBTN)))->SetCheck(1); TLDlg->GetDlgItem(IDC_INSTANCEALINGMENTBTN)->ShowWindow(SW_SHOW); TLDlg->GetDlgItem(IDC_INSTANCETYPEBTN)->ShowWindow(SW_SHOW); // TLDlg->GetDlgItem(IDC_MULTIDROP)->ShowWindow(SW_HIDE); TLDlg->ShowWindow(SW_SHOW); return 0; } void CInstanceWindow::OnSize(UINT nType, int cx, int cy) { CEditorChildWnd::OnSize(nType, cx, cy); if(TLDlg) { TLDlg->SetWindowPos(NULL,0,0,cx,cy,SWP_NOZORDER); TLDlg->m_TabCtrl.SetWindowPos(NULL,0,0,cx,cy,SWP_NOZORDER); RECT r,l,b; TLDlg->m_TabCtrl.GetClientRect(&r); TLDlg->m_TabCtrl.GetItemRect(0,&l); TLDlg->GetDlgItem(IDC_INSTANCETYPEBTN)->GetClientRect(&b); TLDlg->m_ObjList.SetWindowPos(NULL,3,l.bottom + 3,r.right - 7,r.bottom - l.bottom - 14 - b.bottom,SWP_NOZORDER); CButton* typeButton = (CButton*)(TLDlg->GetDlgItem(IDC_INSTANCETYPEBTN)); CButton* alignButton = (CButton*)(TLDlg->GetDlgItem(IDC_INSTANCEALINGMENTBTN)); typeButton->GetWindowRect(&r); typeButton->SetWindowPos(NULL,cx / 2 - (r.right - r.left) - 10, cy - 17 - (r.bottom - r.top) / 2, r.right - r.left, r.bottom - r.top, SWP_NOZORDER); alignButton->SetWindowPos(NULL,cx / 2 + 10, cy - 17 - (r.bottom - r.top) / 2, r.right - r.left, r.bottom - r.top, SWP_NOZORDER); } } void CInstanceWindow::FillTabBox(int tab) { // int lastSortType = -1; if(theApp.m_editorState != CMW4GameEdApp::NoGameIdleState && theApp.m_editorState != CMW4GameEdApp::InitializingState) { if (tab < 0) tab = TLDlg->m_TabCtrl.GetCurSel(); switch(tab) { case MECH_TAB: { ChainIteratorOf iterator(&mechList); FillTabBox(iterator); break; } case BUILDING_TAB: { ChainIteratorOf iterator(&buildingList); FillTabBox(iterator); break; } case VEHICLE_TAB: { ChainIteratorOf iterator(&vehicleList); FillTabBox(iterator); break; } case MISC_TAB: { ChainIteratorOf iterator(&miscList); FillTabBox(iterator); break; } } } } void CInstanceWindow::FillTabBox(ChainIteratorOf &iterator) { TLDlg->m_ObjList.ResetContent(); TabList* item; while ((item = iterator.ReadAndNext()) != NULL) { int index = TLDlg->m_ObjList.AddString(item->itemString); TLDlg->m_ObjList.SetItemDataPtr(index,(void*)LPCTSTR(item->data)); } } void CInstanceWindow::ClearInstanceLists() { TabList* current; ChainIteratorOf mechIterator(&mechList); while((current = mechIterator.GetCurrent()) != NULL) { mechIterator.Remove(); mechIterator.First(); delete current; } ChainIteratorOf buildingIterator(&buildingList); while((current = buildingIterator.GetCurrent()) != NULL) { buildingIterator.Remove(); buildingIterator.First(); delete current; } ChainIteratorOf vehicleIterator(&vehicleList); while((current = vehicleIterator.GetCurrent()) != NULL) { vehicleIterator.Remove(); vehicleIterator.First(); delete current; } ChainIteratorOf miscIterator(&miscList); while((current = miscIterator.GetCurrent()) != NULL) { miscIterator.Remove(); miscIterator.First(); delete current; } } void CInstanceWindow::ResetInstanceLists() { ClearInstanceLists(); Check_Object(Map::Instance); ChainIteratorOf iterator(&Map::Instance->childEntityChain); Entity* entity; while((entity = iterator.ReadAndNext()) != NULL) { if (entity->IsDerivedFrom(EditorLatticeNode::DefaultData) || // && !theApp.m_showLattice) || entity->IsDerivedFrom(Adept::DropZone::DefaultData) || entity->IsDerivedFrom(EditorBoundaryNode::DefaultData) || entity->IsDerivedFrom(MechWarrior4::Objective::DefaultData) || entity->IsDerivedFrom(EditorDropZonePoint::DefaultData) || entity->IsDerivedFrom(EditorPathNode::DefaultData) || entity->IsDerivedFrom(CameraShip::DefaultData) || entity->IsDerivedFrom(MechWarrior4::Path::DefaultData) || entity->IsDerivedFrom(EffectGenerator::DefaultData) ) continue; AddInstance(entity,false); } FillTabBox(); } BOOL CInstanceWindow::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult) { if (UINT(wParam) == IDC_OBJECTTAB) FillTabBox(((NMHDR*)(lParam))->code); *pResult = 0; return CEditorChildWnd::OnNotify(wParam, lParam, pResult); } void CInstanceWindow::AddInstance(Entity* entity, bool fill) { Check_Object(entity); if (entity->IsDerivedFrom(EditorPathNode::DefaultData) || entity->IsDerivedFrom(Adept::Driver::DefaultData)) { return; } TabList* newNode = new TabList; newNode->itemString = entity->instanceName; newNode->itemPath = ""; newNode->data = DWORD(entity); if(entity->IsDerivedFrom(Mech::DefaultData)) { mechList.Add(newNode); } else if(entity->IsDerivedFrom(Building::DefaultData) || entity->IsDerivedFrom(Turret::DefaultData)) { buildingList.Add(newNode); } else if(entity->IsDerivedFrom(Vehicle::DefaultData) ) { vehicleList.Add(newNode); } else { // BS to make drop nodes transparent to user if (entity->IsDerivedFrom(EditorDropNode::DefaultData)) { EditorDropNode* node; node = Cast_Object(EditorDropNode*,entity); newNode->itemString = node->dropZone->instanceName; } if (entity->IsDerivedFrom(EditorCameraShip::DefaultData)) { EditorCameraShip* node; node = Cast_Object(EditorCameraShip*,entity); newNode->itemString = node->cameraShip->instanceName; } // else if (entity->IsDerivedFrom(MechWarrior4::Objective::DefaultData)) else if (entity->IsDerivedFrom(EditorObjectiveMarker::DefaultData)) { EditorObjectiveMarker* node; node = Cast_Object(EditorObjectiveMarker*,entity); newNode->itemString = node->objective->instanceName; } else if (entity->IsDerivedFrom(EditorMovementPath::DefaultData)) { EditorMovementPath* node; node = Cast_Object(EditorMovementPath*,entity); newNode->itemString = node->pathSlot.GetCurrent()->instanceName; } miscList.Add(newNode); } if (fill) FillTabBox(); } void CInstanceWindow::RemoveInstance(Entity* entity) { TabList* current; if(entity->IsDerivedFrom(Mech::DefaultData)) { ChainIteratorOf iterator(&mechList); while((current = iterator.ReadAndNext()) != NULL) { if (current->data == DWORD(entity)) { mechList.Remove(current); break; } } } else if(entity->IsDerivedFrom(Building::DefaultData) || entity->IsDerivedFrom(Turret::DefaultData)) { ChainIteratorOf iterator(&buildingList); while((current = iterator.ReadAndNext()) != NULL) { if (current->data == DWORD(entity)) { buildingList.Remove(current); break; } } } else if(entity->IsDerivedFrom(Vehicle::DefaultData) ) { ChainIteratorOf iterator(&vehicleList); while((current = iterator.ReadAndNext()) != NULL) { if (current->data == DWORD(entity)) { vehicleList.Remove(current); break; } } } else { ChainIteratorOf iterator(&miscList); while((current = iterator.ReadAndNext()) != NULL) { if (current->data == DWORD(entity)) { miscList.Remove(current); break; } } } FillTabBox(); } void CInstanceWindow::OnRButtonDown(UINT nFlags, CPoint point) { if (Application::Instance->GetApplicationState() == ApplicationStateEngine::RunningGameState && theApp.m_editorState != CMW4GameEdApp::AddingObjectState) { BOOL outside; UINT selected = TLDlg->m_ObjList.ItemFromPoint(point,outside); TLDlg->m_ObjList.SetSel(-1,FALSE); TLDlg->m_ObjList.SetSel(selected,TRUE); Entity* entity = (Entity*)TLDlg->m_ObjList.GetItemData(selected); CMenu menu; if (entity->IsDerivedFrom(EditorLight::DefaultData)) { VERIFY(menu.LoadMenu(IDR_LIGHTPOPUP)); } else { VERIFY(menu.LoadMenu(IDR_OBJECTPOPUP)); } CMenu* pPopup = menu.GetSubMenu(0); ASSERT(pPopup != NULL); CPoint point; GetCursorPos(&point); CSelectionList::Instance->ClearSelectionList(); TLDlg->m_ObjList.ScreenToClient(&point); if (entity->IsDerivedFrom(Entity::DefaultData)) { if (entity->IsDerivedFrom(EditorLight::DefaultData)) { if (entity->IsDerivedFrom(EditorPointLight::DefaultData) || entity->IsDerivedFrom(EditorSpotLight::DefaultData)) { pPopup->InsertMenu(-1,MF_BYPOSITION,ID_OBJ_GOTOINSTANCE,"Goto Instance"); } } else if ((!entity->IsDerivedFrom(MechWarrior4::Path::DefaultData)) && (!entity->IsDerivedFrom(DropZone::DefaultData)) && !entity->IsDerivedFrom(EditorWaypoint::DefaultData) && !entity->IsDerivedFrom(EditorPathNode::DefaultData) && !entity->IsDerivedFrom(EditorLatticeNode::DefaultData) && !entity->IsDerivedFrom(EditorBoundaryNode::DefaultData) && !entity->IsDerivedFrom(EditorDropNode::DefaultData) && !entity->IsDerivedFrom(EditorDropZonePoint::DefaultData) && !entity->IsDerivedFrom(EditorObjectiveMarker::DefaultData) && !entity->IsDerivedFrom(EditorCameraShip::DefaultData)) { pPopup->InsertMenu(-1,MF_BYPOSITION,ID_OBJ_EDITDRIVER,"Edit Driver..."); pPopup->InsertMenu(-1,MF_BYPOSITION,ID_OBJ_SPECIFYSCRIPT,"Specify ABL Script..."); pPopup->InsertMenu(-1,MF_BYPOSITION,ID_OBJ_CLEARAI,"Clear AI Info"); pPopup->InsertMenu(-1,MF_SEPARATOR); pPopup->InsertMenu(-1,MF_BYPOSITION,ID_OBJ_ABLMEMORY,"Edit Memory Cells..."); pPopup->InsertMenu(-1,MF_BYPOSITION,ID_OBJ_EDITSKILL,"Edit Skills..."); // pPopup->InsertMenu(-1,MF_BYPOSITION,ID_OBJ_EDITSCRIPT,"Edit ABL Script..."); } } if (entity->IsDerivedFrom(EditorObjectiveMarker::DefaultData)) { pPopup->RemoveMenu(ID_OBJ_GOTOINSTANCE,MF_BYCOMMAND); pPopup->InsertMenu (-1,MF_BYPOSITION,ID_OBJ_EDITOBJECTIVE,"Edit Objective..."); } if (entity->IsDerivedFrom(Vehicle::DefaultData)) { pPopup->GetSubMenu(0)->InsertMenu(1,MF_BYPOSITION,ID_OBJ_DAMAGEOBJARMOR,"Armor..."); pPopup->GetSubMenu(0)->InsertMenu(2,MF_BYPOSITION,ID_OBJ_DAMAGEOBJINTERNAL,"Internal..."); pPopup->GetSubMenu(0)->InsertMenu(3,MF_BYPOSITION,ID_OBJ_SUBSYSTEM,"Subsystems..."); } CSelectionList::Instance->AddSelection(entity); TLDlg->m_ObjList.ClientToScreen(&point); pPopup->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y, this); // changed back to this line, menu messages where being routed to tldlg, // pPopup->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y, TLDlg); // but all of the handlers where in this class. } CEditorChildWnd::OnRButtonDown(nFlags, point); } int CInstanceWindow::GetSelectedObject() { int value = -1; int selCount = TLDlg->m_ObjList.GetSelCount(); Verify(selCount == 1); int* selected = new int; TLDlg->m_ObjList.GetSelItems(1,selected); value = *selected; delete selected; Verify(value >= 0); return value; } void CInstanceWindow::OnObjName() { ChangeObjName(); } void CInstanceWindow::ChangeObjName() { int index = GetSelectedObject(); Entity* entity = (Entity*)TLDlg->m_ObjList.GetItemData(index); Check_Object(entity); CGenericTextDlg dlg; dlg.m_Title = "Set Object Name"; dlg.m_MessageText = "Enter the new name of this object"; if (entity->IsDerivedFrom(EditorDropNode::DefaultData)) { EditorDropNode* node; node = Cast_Object(EditorDropNode*,entity); entity = node->dropZone; } if (entity->IsDerivedFrom(EditorCameraShip::DefaultData)) { EditorCameraShip* node; node = Cast_Object(EditorCameraShip*,entity); entity = node->cameraShip; } else if (entity->IsDerivedFrom(MechWarrior4::Objective::DefaultData)) { EditorObjectiveMarker* node; node = Cast_Object(EditorObjectiveMarker*,entity); entity = node->objective; } else if (entity->IsDerivedFrom(EditorMovementPath::DefaultData)) { EditorMovementPath* node; node = Cast_Object(EditorMovementPath*,entity); entity = node->pathSlot.GetCurrent(); } else if (entity->IsDerivedFrom(EditorObjectiveMarker::DefaultData)) { EditorObjectiveMarker* node; node = Cast_Object(EditorObjectiveMarker*,entity); entity =node->objective; } dlg.m_EditText = entity->instanceName; if (dlg.DoModal() == IDOK) { EntityManager::Instance->GetNameSocket()->Remove(entity); entity->instanceName = dlg.m_EditText; EntityManager::Instance->GetNameSocket()->AddValue(entity, entity->instanceName); /* DWORD data = TLDlg->m_ObjList.GetItemData(index); TLDlg->m_ObjList.DeleteString(index); index = TLDlg->m_ObjList.AddString(entity->instanceName); TLDlg->m_ObjList.SetItemData(index,data); */ Check_Object(NameTable::Instance); NameTable::Instance->SetName(entity->objectID, entity->instanceName); NameTable::Instance->IsValid(); theApp.MakeObjectNamesUnique(); ResetInstanceLists(); } } void CInstanceWindow::OnObjParameters() { Entity* entity = (Entity*)TLDlg->m_ObjList.GetItemData(GetSelectedObject()); Check_Object(entity); EditEntityDlg edit_dialog(NULL, entity); edit_dialog.DoModal(); } void CInstanceWindow::OnObjTranslation() { Entity* entity = (Entity*)TLDlg->m_ObjList.GetItemData(GetSelectedObject()); Check_Object(entity); if(!theApp.displayWindow->translationDlg) { theApp.displayWindow->translationDlg = new CTransDlg; Register_Pointer(theApp.displayWindow->translationDlg); theApp.displayWindow->translationDlg->Create(CTransDlg::IDD,this); } theApp.displayWindow->translationDlg->SetObject(entity,theApp.GetEntityData(entity)); theApp.displayWindow->translationDlg->ShowWindow(SW_SHOW); } void CInstanceWindow::OnObjRemoveinstance() { theApp.currentCommand = new DeleteCommand(); Register_Object(theApp.currentCommand); CSelectionList::Instance->ClearSelectionList(false); theApp.m_editorState = CMW4GameEdApp::SelectingObjectState; theApp.undoChain.Add(theApp.currentCommand); theApp.currentCommand = NULL; theApp.toolBar->EnableButton(ID_EDIT_UNDO); } void CInstanceWindow::OnObjGotoinstance() { Entity* entity = (Entity*)TLDlg->m_ObjList.GetItemData(GetSelectedObject()); if (entity->IsDerivedFrom(EditorMovementPath::DefaultData)) { EditorMovementPath* path; path = Cast_Object(EditorMovementPath*,entity); ChainIteratorOf iterator(&path->pathNodes); entity = iterator.GetCurrent(); } Check_Object(entity); LinearMatrix4D matrix; Point3D newPoint; YawPitchRoll newOrientation; // // Get the current angle and position above ground for the camera and figure out where to place the camera when we set focus // LinearMatrix4D oldCameraMatrix; Point3D oldCameraPosition; YawPitchRoll oldCameraOrientation; Point3D intersectCameraWithGround; oldCameraMatrix= Player::Instance->GetLocalToWorld(); oldCameraOrientation = oldCameraMatrix; oldCameraPosition = oldCameraMatrix; // cast a line from this point to the ground or object in center of view, in the current direction and get the distance. Adept::Entity *entity_hit = NULL; Stuff::Line3D line; line.m_length = 1000.0f; oldCameraMatrix.GetLocalForwardInWorld(&(line.m_direction)); line.SetOrigin(oldCameraPosition); Stuff::Normal3D inormal; Stuff::Line3D iline; Stuff::Normal3D normal; Check_Object(CollisionGrid::Instance); Entity::CollisionQuery query(&line, &normal, Adept::Entity::CanBeWalkedOnFlag, NULL); entity_hit = CollisionGrid::Instance->ProjectLine(&query); // // If the camera is facing anything it can collide with like the ground or an object within 1000M we have a distance for the camera // if (entity_hit) { line.FindEnd(&intersectCameraWithGround); // now we have an intersection distance in line matrix = entity->GetLocalToWorld(); newPoint = matrix; newOrientation = oldCameraOrientation; if (newPoint.x < -(theApp.displayWindow->mapX*0.5f)) newPoint.x = 1.0f; else if (newPoint.x > (theApp.displayWindow->mapX*0.5f)) newPoint.x = (theApp.displayWindow->mapX*0.5f) - 1.0f; if (newPoint.z < -(theApp.displayWindow->mapZ*0.5f)) newPoint.z = 1.0f; else if (newPoint.z > (theApp.displayWindow->mapZ*0.5f)) newPoint.z = (theApp.displayWindow->mapZ*0.5f) - 1.0f; // // reverse the direction of the line that we used to get the position of the camera from the nearest obstacle // then we can use this line to position the camera relative to the entity we are going to // line.m_direction.Negate(line.m_direction); line.SetOrigin(newPoint); line.FindEnd(&newPoint); // newPoint should now be where we want the camera } else // // This is the old code. If for some reason the camera isn't pointing at anything (up, horizontal, etc...) // then we will just rely on the old positioning code. // { matrix = entity->GetLocalToWorld(); newPoint = matrix; newOrientation = matrix; newPoint.z -= Cos(newOrientation.yaw) * 25; newPoint.x -= Sin(newOrientation.yaw) * 25; if (newPoint.x < 0) newPoint.x = 1.0f; else if (newPoint.x > theApp.displayWindow->mapX) newPoint.x = theApp.displayWindow->mapX - 1.0f; if (newPoint.z < 0) newPoint.z = 1.0f; else if (newPoint.z > theApp.displayWindow->mapZ) newPoint.z = theApp.displayWindow->mapZ - 1.0f; line.m_length = 1000.0f; line.m_direction = Vector3D::Down; Check_Object(CollisionGrid::Instance); newPoint.y = 600; line.SetOrigin(newPoint); Entity::CollisionQuery query(&line, &normal, Entity::AlwaysCollidesMask, NULL); entity_hit = CollisionGrid::Instance->ProjectLine(&query); while (entity_hit) { newPoint.z -= 25.0f; line.SetOrigin(newPoint); Entity::CollisionQuery query(&line, &normal, Entity::AlwaysCollidesMask, NULL); entity_hit = CollisionGrid::Instance->ProjectLine(&query); } Verify(newPoint.z >= 1.0f); newPoint.y = theApp.displayWindow->GetMapPointVertical(newPoint.x,newPoint.z); } matrix.BuildTranslation(newPoint); matrix.BuildRotation(newOrientation); Player::Instance->SetNewLocalToParent(matrix); Player::Instance->SyncMatrices(true); theApp.overviewWindow->DrawWindow(); } void CInstanceWindow::CheckHiddenObject(Entity* entity) { if (TLDlg->m_TabCtrl.GetCurSel() == 3) { if (entity->IsDerivedFrom(EditorMovementPath::DefaultData)) { theApp.m_showPaths = false; theApp.OnToolsMovmentlayerShowpaths(); } else if (entity->IsDerivedFrom(EditorDropNode::DefaultData)) { theApp.m_showDropZones = false; theApp.OnToolsMovmentlayerShowdropzones(); } else if (entity->IsDerivedFrom(EditorObjectiveMarker::DefaultData)) { theApp.m_showAI = false; theApp.OnToolsMovmentlayerShowobjectives(); } } } void CInstanceWindow::OnLButtonUp(UINT nFlags, CPoint point) { if (theApp.m_editorState == CMW4GameEdApp::MovingObjectState) return; int selCount = TLDlg->m_ObjList.GetSelCount(); int* selected = new int [selCount]; TLDlg->m_ObjList.GetSelItems(selCount,selected); CSelectionList::Instance->ClearSelectionList(); for (int i = 0; i < selCount; i++) { Entity* entity = (Entity*)TLDlg->m_ObjList.GetItemData(selected[i]); CSelectionList::Instance->AddSelection(entity); CheckHiddenObject(entity); } if (theApp.displayWindow->translationDlg->IsWindowVisible()) { if (selCount == 1) { Entity *tmpentity=(Entity*)TLDlg->m_ObjList.GetItemData(selected[0]); theApp.displayWindow->translationDlg->SetObject(tmpentity,theApp.GetEntityData(tmpentity)); } else { theApp.displayWindow->translationDlg->ShowWindow(SW_HIDE); } } delete [] selected; CEditorChildWnd::OnLButtonUp(nFlags, point); } void CInstanceWindow::ResetSel() { TLDlg->m_ObjList.SetSel(-1,FALSE); ChainIteratorOf iterator(&CSelectionList::Instance->selectionList); CSelectionNode* selection; while ((selection = iterator.ReadAndNext()) != NULL) { int index = TLDlg->m_ObjList.FindStringExact(0,selection->selectedEntity->instanceName); if (index != LB_ERR) TLDlg->m_ObjList.SetSel(index); } } void CInstanceWindow::OnObjDamageobjArmor() { Entity* entity = (Entity*)TLDlg->m_ObjList.GetItemData(GetSelectedObject()); Check_Object(entity); EditEntityDlg edit_dialog(NULL,entity,EDIT_DAMAGE_OBJECTARMOR); edit_dialog.DoModal(); } void CInstanceWindow::OnObjDamageobjInternal() { Entity* entity = (Entity*)TLDlg->m_ObjList.GetItemData(GetSelectedObject()); Check_Object(entity); EditEntityDlg edit_dialog(NULL,entity,EDIT_DAMAGE_OBJECTINTERNAL); edit_dialog.DoModal(); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void EditObjective (Entity *entity); void CInstanceWindow::OnObjEditObjective() { EditObjective ((Entity*)TLDlg->m_ObjList.GetItemData(GetSelectedObject())); } void EditAIDriver (Entity *entity); void CInstanceWindow::OnObjEditDriver() { EditAIDriver ((Entity*)TLDlg->m_ObjList.GetItemData(GetSelectedObject())); } void CInstanceWindow::OnObjSpecifyScript() { Entity* entity; entity = (Entity*)TLDlg->m_ObjList.GetItemData(GetSelectedObject()); OnObjSpecifyScript(entity); } void CInstanceWindow::OnObjSpecifyScript(Entity* entity) { MWObject *obj; if (!entity->IsDerivedFrom (MWObject::DefaultData)) { MessageBox("Object is not derived from MWobject","not MWObject"); // localize return; } obj = Cast_Object (MWObject *,entity); if (obj->m_AI == NULL) { MessageBox("You must attach a driver first.","Driver Not Found"); // localize return; } char scriptPath[MAX_PATH],oldDir[MAX_PATH]; OPENFILENAME ofn; _getcwd(oldDir,MAX_PATH - 1); memset(&scriptPath,0,MAX_PATH); memset(&ofn,0,sizeof(ofn)); if (obj->m_AI->GetScriptName()) { char *p,tmp[MAX_PATH]; strncpy(tmp,obj->m_AI->GetScriptName(),MAX_PATH); p = __mbsrchr(tmp,'\\'); if (p) strncpy(scriptPath,++p,MAX_PATH); } ofn.lStructSize = sizeof(ofn); ofn.hwndOwner = NULL; ofn.lpstrFilter = "ABL files {*.ABL}\0*.abl\0All Files {*.*}\0*.*\0\0"; ofn.lpstrFile = scriptPath; ofn.nMaxFile = MAX_PATH; ofn.Flags = OFN_FILEMUSTEXIST; ofn.lpstrDefExt = "abl"; char path[MAX_PATH],*p; strcpy(path,theApp.missionFileName); p = __mbsrchr(path,'\\'); *p = 0; strcat(path,"\\Scripts"); if (_chdir(path) != 0) { if (!CreateDirectory(path,NULL)) { DWORD err = GetLastError(); sprintf(path,"Could not create Scripts directory. Error %d",err); MessageBox(path,"File Error"); // localize return; } if (_chdir(path) != 0) { DWORD err = GetLastError(); sprintf(path,"Could not find Scripts directory. Error %d",err); MessageBox(path,"File Error"); // localize return; } } if (GetOpenFileName(&ofn)) { _chdir(oldDir); char path_buffer[_MAX_PATH],drive[_MAX_DRIVE],dir[_MAX_DIR],fname[_MAX_FNAME],ext[_MAX_EXT]; _splitpath(ofn.lpstrFile,drive,dir,fname,ext); p = __mbsrchr(dir,'\\'); *p = 0; p = __mbschr(dir,'\\'); p++; p = __mbschr(p,'\\'); p++; if (stricmp(strstr(p,"Content"),strstr(path,"Content")) != 0) { sprintf(path_buffer,"%s\\%s%s",path,fname,ext); if (!CopyFile(ofn.lpstrFile,path_buffer,TRUE)) { DWORD err = GetLastError(); if (err == 80) // file exists { if (MessageBox("A file of that name already exists in the mission script folder. Do you wish to overwrite that file?","File Error",MB_YESNO) == IDYES) CopyFile(ofn.lpstrFile,path_buffer,FALSE); } else { sprintf(path,"Could not copy ABL file to current mission folder. Error %d",err); MessageBox(path,"File Error"); // localize return; } } if (!SetFileAttributes(path_buffer,FILE_ATTRIBUTE_NORMAL)) { DWORD err = GetLastError(); sprintf(path,"Could not clear readonly flag on ABL file in current mission folder, please do so yourself. Error %d",err); MessageBox(path,"File Error"); // localize return; } } else strcpy(path_buffer,ofn.lpstrFile); if (obj->m_AI) { ABL::ABLError err; if (!obj->m_AI->LoadScript(strstr(path_buffer,"Content"))) { char errString[256]; sprintf(errString,"%s on Line %d.",err.String(),err.Line()); MessageBox(errString,"ABL Error"); ObjEditScript(path_buffer,err.Line()); } } else { ABL::ABLError err; AI* ai; ai = Cast_Object(AI*,entity); ai->LoadScript(ofn.lpstrFile); } } _chdir(oldDir); } void CInstanceWindow::OnObjEditScript() { ObjEditScript(); } void CInstanceWindow::ObjEditScript(char* file, int line) { line -= 1; Entity* entity = (Entity*)TLDlg->m_ObjList.GetItemData(GetSelectedObject()); MWObject *obj; if (!entity->IsDerivedFrom (MWObject::DefaultData)) { MessageBox("Object is not derived from MWobject","not mwobject"); // localize return; } obj = Cast_Object (MWObject *,entity); if (obj->m_AI == NULL) { MessageBox("You must attach a driver first.","Driver Not Found"); // localize return; } char scriptPath[MAX_PATH]; if (file) strncpy(scriptPath,file,MAX_PATH - 1); else strncpy(scriptPath,obj->m_AI->GetScriptName(),MAX_PATH - 1); if (!scriptWnd) { scriptWnd = new CEditWnd(scriptPath); RECT r; r.left = 50; r.top = 50; r.right = 690; r.bottom = 530; scriptWnd->Create(NULL,"AI Script",NULL,r); } else if (file) { scriptWnd->LoadFile(file); scriptWnd->SetWindowText("AI Script"); } scriptWnd->ShowWindow(SW_SHOW); scriptWnd->BringWindowToTop(); scriptWnd->editWnd.LineScroll(line - scriptWnd->editWnd.GetFirstVisibleLine()); POINT p; p.x = p.y = 50; SetCaretPos(p); ShowCaret(); scriptWnd->editWnd.SetScrollPos(SB_VERT,scriptWnd->editWnd.GetFirstVisibleLine()); scriptWnd->editWnd.SetSel(scriptWnd->editWnd.LineIndex(line),scriptWnd->editWnd.LineIndex(line) + scriptWnd->editWnd.LineLength(line)); CallbackEntity = entity; scriptWnd->CloseCallback = InstanceEditScriptCallback; } void CInstanceWindow::OnLButtonDblClk(UINT nFlags, CPoint point) { if (!TLDlg->m_ObjList.GetSelCount()) return; Entity* entity = (Entity*)TLDlg->m_ObjList.GetItemData(GetSelectedObject()); CheckHiddenObject(entity); if (entity->IsDerivedFrom(EditorMovementPath::DefaultData) || entity->IsDerivedFrom(EditorAmbientLight::DefaultData) || entity->IsDerivedFrom(EditorInfiniteLight::DefaultData)) { MessageBox("Cannot move that type of object","Move Error"); // localize } else { theApp.m_editorState = CMW4GameEdApp::MovingObjectState; theApp.currentCommand = new MoveCommand(entity); CSelectionList::Instance->RemoveCollision(); Register_Object(theApp.currentCommand); if (CSelectionList::Instance->GetSelectionCount() > 1 && theApp.displayWindow->translationDlg->IsWindowVisible()) theApp.displayWindow->translationDlg->ShowWindow(SW_HIDE); if (CSelectionList::Instance->GetSelectionCount() > 1 && theApp.displayWindow->latticeLinkDlg->IsWindowVisible()) theApp.displayWindow->latticeLinkDlg->ShowWindow(SW_HIDE); } // CEditorChildWnd::OnLButtonDblClk(nFlags, point); } void CInstanceWindow::OnObjAlignment() { theApp.displayWindow->OnObjAlignment((Entity*)TLDlg->m_ObjList.GetItemData(GetSelectedObject())); } void CInstanceWindow::OnEditLight() { EditorLight* editorLight = (EditorLight*) TLDlg->m_ObjList.GetItemData(GetSelectedObject()); theApp.CreateLightDlg(); theApp.lightDlg->SetLight(editorLight); theApp.lightDlg->ShowWindow(SW_SHOW); } void CInstanceWindow::OnClearAI() { Entity* entity; entity = (Entity*)TLDlg->m_ObjList.GetItemData(GetSelectedObject()); OnClearAI(entity); } void CInstanceWindow::OnClearAI(Entity* entity) { MWObject *obj; obj = Cast_Object (MWObject *,entity); if (obj->m_AI) { NameTable::Instance->RemoveEntry(obj->m_AI->objectID); NameTable::Instance->IsValid(); obj->m_AI->SentenceToDeathRow(); obj->m_AI = NULL; // clear the driver } } void CInstanceWindow::OnABLMemory() { Entity* entity; entity = (Entity*)TLDlg->m_ObjList.GetItemData(GetSelectedObject()); OnABLMemory(entity); } void CInstanceWindow::OnABLMemory(Entity* entity) { MWObject *obj; if (!entity->IsDerivedFrom (MWObject::DefaultData)) { MessageBox("Object is not derived from MWobject","not mwobject"); // localize return; } obj = Cast_Object (MWObject *,entity); if (obj->m_AI == NULL) { MessageBox("You must attach a driver first.","Driver Not Found"); // localize return; } AblMemDlg dlg(entity); dlg.DoModal(); } void CInstanceWindow::OnEditSkill() { Entity* entity; entity = (Entity*)TLDlg->m_ObjList.GetItemData(GetSelectedObject()); OnEditSkill(entity); } void CInstanceWindow::OnEditSkill(Entity* entity) { MWObject *obj; if (!entity->IsDerivedFrom (MWObject::DefaultData)) { MessageBox("Object is not derived from MWobject","not mwobject"); // localize return; } obj = Cast_Object (MWObject *,entity); if (obj->m_AI == NULL) { MessageBox("You must attach a driver first.","Driver Not Found"); // localize return; } EditSkillsDlg dlg(entity); dlg.DoModal(); }