Files
firestorm/Gameleap/code/mw4/Code/MW4GameEd/InstanceWindow.cpp
T
Cyd 2b8ca921cb Initial full mirror of c:\VWE (source + assets + toolchain + outputs) via Git LFS
Complete disaster-recovery snapshot: engine/game source, game data assets,
VC6 toolchain + DX SDKs, build outputs, deployed game, and _UNUSED archive.
Large binaries in Git LFS; text preserved byte-for-byte (core.autocrlf=false,
no eol attributes). See RECOVERY.md for the one-clone rebuild procedure.
2026-06-24 21:28:16 -05:00

1196 lines
33 KiB
C++

// InstanceWindow.cpp : implementation file
//
#include "stdafx.h"
#include "MW4GameEd.h"
#include "EditorChildWnd.h"
#include <direct.h>
#include <stdlib.h>
#include <stdio.h>
#include <Adept\Map.hpp>
#include "MoveCommand.h"
#include "AddCommand.h"
#include <Adept\EntityManager.hpp>
#include <Adept\Mission.hpp>
#include <Adept\Connection.hpp>
#include <Adept\Application.hpp>
#include <MW4\Mech.hpp>
#include <MW4\Vehicle.hpp>
#include <MW4\Building.hpp>
#include <MW4\Turret.hpp>
#include "InstanceWindow.h"
#include "GenericTextDlg.h"
#include "transDlg.h"
#include "DeleteCommand.h"
#include <Adept\Player.hpp>
#include "EditorWaypoint.h"
#include "GenericListDlg.h"
#include <mw4\AI.hpp>
#include <mw4\EffectGenerator.hpp>
#include <Adept\DropZone.hpp>
#include <Adept\NameTable.hpp>
#include <Adept\CollisionGrid.hpp>
#include "LatticeLinkDlg.h"
#include <MW4\CombatAI.hpp>
#include "LightWnd.h"
#include "AblMemDlg.h"
#include "DisplayWindow.h"
#include "OverviewWindow.h"
#include "Selection.h"
#include "editskilldlg.hpp"
#include <mbstring.h>
#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<TabList*> iterator(&mechList);
FillTabBox(iterator);
break;
}
case BUILDING_TAB:
{
ChainIteratorOf<TabList*> iterator(&buildingList);
FillTabBox(iterator);
break;
}
case VEHICLE_TAB:
{
ChainIteratorOf<TabList*> iterator(&vehicleList);
FillTabBox(iterator);
break;
}
case MISC_TAB:
{
ChainIteratorOf<TabList*> iterator(&miscList);
FillTabBox(iterator);
break;
}
}
}
}
void CInstanceWindow::FillTabBox(ChainIteratorOf<TabList*> &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<TabList*> mechIterator(&mechList);
while((current = mechIterator.GetCurrent()) != NULL)
{
mechIterator.Remove();
mechIterator.First();
delete current;
}
ChainIteratorOf<TabList*> buildingIterator(&buildingList);
while((current = buildingIterator.GetCurrent()) != NULL)
{
buildingIterator.Remove();
buildingIterator.First();
delete current;
}
ChainIteratorOf<TabList*> vehicleIterator(&vehicleList);
while((current = vehicleIterator.GetCurrent()) != NULL)
{
vehicleIterator.Remove();
vehicleIterator.First();
delete current;
}
ChainIteratorOf<TabList*> miscIterator(&miscList);
while((current = miscIterator.GetCurrent()) != NULL)
{
miscIterator.Remove();
miscIterator.First();
delete current;
}
}
void CInstanceWindow::ResetInstanceLists()
{
ClearInstanceLists();
Check_Object(Map::Instance);
ChainIteratorOf<Entity *> 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<TabList*> 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<TabList*> iterator(&buildingList);
while((current = iterator.ReadAndNext()) != NULL)
{
if (current->data == DWORD(entity))
{
buildingList.Remove(current);
break;
}
}
}
else if(entity->IsDerivedFrom(Vehicle::DefaultData) )
{
ChainIteratorOf<TabList*> iterator(&vehicleList);
while((current = iterator.ReadAndNext()) != NULL)
{
if (current->data == DWORD(entity))
{
vehicleList.Remove(current);
break;
}
}
}
else
{
ChainIteratorOf<TabList*> 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<EditorPathNode*> 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<CSelectionNode*> 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();
}