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.
383 lines
12 KiB
C++
383 lines
12 KiB
C++
#include "stdafx.h"
|
|
#include "MW4GameEd.h"
|
|
#include "MoveCommand.h"
|
|
#include "EditorWaypoint.h"
|
|
#include <Adept\Player.hpp>
|
|
#include <Adept\Entity.hpp>
|
|
#include <Adept\Interface.hpp>
|
|
#include <Adept\EntityManager.hpp>
|
|
#include <Adept\VideoRenderer.hpp>
|
|
#include <Adept\CameraComponent.hpp>
|
|
#include <Adept\Map.hpp>
|
|
#include "DisplayWindow.h"
|
|
#include "OverviewWindow.h"
|
|
#include "Selection.h"
|
|
extern CMW4GameEdApp theApp;
|
|
|
|
MoveCommand::MoveCommand(Entity *object)
|
|
: Command()
|
|
{
|
|
Check_Object(object);
|
|
moveOffset = Point3D::Identity;
|
|
cursorPosition = object->GetLocalToWorld();
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
MoveCommand::~MoveCommand()
|
|
{
|
|
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
MoveCommand::Execute()
|
|
{
|
|
Move();
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
MoveCommand::Undo()
|
|
{
|
|
theApp.MakeObjectsZoneBased();
|
|
|
|
LinearMatrix4D new_local_to_world;
|
|
Point3D target_in_world;
|
|
CSelectionNode *selection_node;
|
|
YawPitchRoll current_rotation;
|
|
Entity* entity;
|
|
|
|
if (!selectedEntities.IsEmpty())
|
|
{
|
|
ChainIteratorOf<CSelectionNode*> iterator(&selectedEntities);
|
|
while((selection_node = iterator.ReadAndNext()) != NULL)
|
|
{
|
|
entity = selection_node->selectedEntity;
|
|
target_in_world = entity->GetLocalToWorld();
|
|
target_in_world -= moveOffset;
|
|
current_rotation = entity->GetLocalToParent();
|
|
|
|
new_local_to_world.BuildTranslation(target_in_world);
|
|
new_local_to_world.BuildRotation(current_rotation);
|
|
|
|
Check_Object(entity);
|
|
entity->SetNewLocalToParent(new_local_to_world);
|
|
entity->SyncMatrices(true);
|
|
|
|
if (entity->IsDerivedFrom(EditorPathNode::DefaultData))
|
|
{
|
|
EditorPathNode* node;
|
|
node = Cast_Object(EditorPathNode*,entity);
|
|
node->pathSlot.GetCurrent()->pathSlot.GetCurrent()->pathPoints[node->index] = target_in_world;
|
|
node->UpdateLinkPointData();
|
|
}
|
|
else if (entity->IsDerivedFrom(EditorBoundaryNode::DefaultData))
|
|
{
|
|
EditorBoundaryNode* node;
|
|
node = Cast_Object(EditorBoundaryNode*,entity);
|
|
(*node->myBoundary)[node->index].x = target_in_world.x;
|
|
(*node->myBoundary)[node->index].y = target_in_world.z;
|
|
node->UpdateLinkPointData();
|
|
}
|
|
else if (entity->IsDerivedFrom(EditorDropNode::DefaultData))
|
|
{
|
|
EditorDropNode* node;
|
|
node = Cast_Object(EditorDropNode*,entity);
|
|
node->dropZone->SetNewLocalToParent(new_local_to_world);
|
|
node->dropZone->SyncMatrices(true);
|
|
|
|
EditorDropZonePoint* point;
|
|
Point3D newPoint;
|
|
LinearMatrix4D matrix = LinearMatrix4D::Identity;
|
|
ChainIteratorOf<EditorDropZonePoint*> iterator(&node->pointChain);
|
|
while((point = iterator.ReadAndNext()) != NULL)
|
|
{
|
|
newPoint = new_local_to_world;
|
|
newPoint -= point->offset;
|
|
newPoint.y = theApp.displayWindow->GetMapPointVertical(newPoint.x,newPoint.z);
|
|
matrix.BuildTranslation(newPoint);
|
|
point->SetNewLocalToParent(matrix);
|
|
point->SyncMatrices(true);
|
|
point->UpdateLinkPointData();
|
|
}
|
|
node->UpdatePoints();
|
|
}
|
|
else if (entity->IsDerivedFrom(EditorDropZonePoint::DefaultData))
|
|
{
|
|
EditorDropZonePoint* node;
|
|
node = Cast_Object(EditorDropZonePoint*,entity);
|
|
node->SetNewLocalToParent(new_local_to_world);
|
|
node->SyncMatrices(true);
|
|
node->UpdateLinkPointData();
|
|
node->dropNode->UpdatePoints();
|
|
}
|
|
/*
|
|
else if (entity->IsDerivedFrom(EditorObjectiveMarker::DefaultData))
|
|
{
|
|
EditorObjectiveMarker* node;
|
|
node = Cast_Object(EditorObjectiveMarker*,entity);
|
|
node->objective->SetNewLocalToParent(new_local_to_world);
|
|
node->objective->SyncMatrices(true);
|
|
}
|
|
*/
|
|
else if (entity->IsDerivedFrom(EditorPointLight::DefaultData))
|
|
{
|
|
EditorPointLight* pointLight;
|
|
pointLight = Cast_Object(EditorPointLight*,entity);
|
|
|
|
pointLight->SetLightToWorldMatrix(pointLight->GetLocalToWorld());
|
|
}
|
|
else if (entity->IsDerivedFrom(EditorSpotLight::DefaultData))
|
|
{
|
|
EditorSpotLight* spotLight;
|
|
spotLight = Cast_Object(EditorSpotLight*,entity);
|
|
|
|
spotLight->SetLightToWorldMatrix(spotLight->GetLocalToWorld());
|
|
}
|
|
else if (entity->IsDerivedFrom(EditorCameraShip::DefaultData))
|
|
{
|
|
EditorCameraShip* node;
|
|
node = Cast_Object(EditorCameraShip*,entity);
|
|
node->cameraShip->SetNewLocalToParent(new_local_to_world);
|
|
node->cameraShip->SyncMatrices(true);
|
|
}
|
|
|
|
}
|
|
}
|
|
theApp.MakeObjectsTileBased();
|
|
theApp.overviewWindow->DrawWindow();
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
MoveCommand::Move()
|
|
{
|
|
//This function needs to run through the list and move all according
|
|
//to the offset of the cursor. This is not going to be as easy as it
|
|
//seems. First just move one.
|
|
|
|
Check_Object(Map::Instance);
|
|
|
|
theApp.MakeObjectsZoneBased();
|
|
|
|
Point3D new_offset;
|
|
LinearMatrix4D new_local_to_world;
|
|
CSelectionNode *selection_node;
|
|
Entity* entity;
|
|
Point3D translation = Point3D::Identity;
|
|
|
|
Check_Object(Player::Instance);
|
|
Check_Object(Player::Instance->playerInterface);
|
|
int x_down = GetAsyncKeyState(KEY_X) & 0x8000;
|
|
int y_down = GetAsyncKeyState(KEY_Y) & 0x8000;
|
|
int z_down = GetAsyncKeyState(KEY_Z) & 0x8000;
|
|
Entity *reticule;
|
|
reticule = Player::Instance->playerInterface->reticuleEntity.GetCurrent();
|
|
if(reticule)
|
|
{
|
|
Point3D world_offset = Player::Instance->playerInterface->reticuleOffset;
|
|
LinearMatrix4D new_local_to_parent = LinearMatrix4D::Identity;
|
|
new_local_to_parent.Multiply(reticule->GetLocalToParent(), world_offset);
|
|
translation = new_local_to_parent;
|
|
}
|
|
else if (!y_down) // make sure we're not trying to move vertically.
|
|
return; // must be pointing at the sky
|
|
|
|
bool x_blocked = false, y_blocked = true, z_blocked = false;
|
|
|
|
if (x_down || y_down || z_down)
|
|
{
|
|
x_blocked = !x_down;
|
|
y_blocked = !y_down;
|
|
z_blocked = !z_down;
|
|
}
|
|
|
|
new_offset = translation;
|
|
new_offset -= cursorPosition;
|
|
|
|
if (x_blocked)
|
|
new_offset.x = 0;
|
|
if (z_blocked)
|
|
new_offset.z = 0;
|
|
|
|
if (!(selectedEntities.IsEmpty()))
|
|
{
|
|
ChainIteratorOf<CSelectionNode*> iterator(&selectedEntities);
|
|
iterator.First();
|
|
while((selection_node = iterator.ReadAndNext()) != NULL)
|
|
{
|
|
entity = selection_node->selectedEntity;
|
|
Point3D target_in_world,old_entity_pos;
|
|
target_in_world = entity->GetLocalToWorld();
|
|
old_entity_pos = target_in_world;
|
|
YawPitchRoll current_rotation;
|
|
current_rotation = entity->GetLocalToParent();
|
|
|
|
if (y_blocked)
|
|
{
|
|
target_in_world += new_offset;
|
|
moveOffset += new_offset;
|
|
|
|
target_in_world.y = theApp.displayWindow->GetMapPointVertical(target_in_world.x,target_in_world.z);
|
|
CEditorEntityData *exdata=theApp.GetEntityData(entity);
|
|
if(exdata)
|
|
target_in_world.y+=exdata->VOffset;
|
|
|
|
}
|
|
else
|
|
{
|
|
Vector2DOf<Scalar> cursor;
|
|
gos_GetMouseInfo(&cursor.x, &cursor.y, NULL, NULL, NULL, NULL);
|
|
|
|
// Clean out the interface data
|
|
|
|
Check_Object(VideoRenderer::Instance);
|
|
EntityComponentWeb *web =
|
|
Cast_Object(EntityComponentWeb*,VideoRenderer::Instance->GetSceneCamera()->GetComponentWeb());
|
|
Interface *intface = Cast_Object(Interface*, web->GetEntity());
|
|
intface->reticuleEntity.Remove();
|
|
|
|
// Figure out the eyeline
|
|
|
|
Line3D world_line;
|
|
VideoRenderer::Instance->GetSceneCamera()->ComputeEyeLine(&world_line, cursor);
|
|
|
|
Point3D point,y_offset;
|
|
point = entity->GetLocalToWorld();
|
|
Vector3D vector(world_line.m_direction.x,0,world_line.m_direction.z);
|
|
Normal3D plane_normal;
|
|
plane_normal.Normalize(vector);
|
|
|
|
Stuff::Plane plane(plane_normal,plane_normal * point);
|
|
|
|
Scalar axis;
|
|
Scalar length = world_line.GetDistanceTo(plane,&axis);
|
|
world_line.Project(length,&y_offset);
|
|
|
|
|
|
target_in_world += new_offset;
|
|
moveOffset += new_offset;
|
|
}
|
|
|
|
if (theApp.gridOn && !(x_down || y_down || z_down))
|
|
theApp.GetGridCoords(target_in_world);
|
|
|
|
|
|
new_local_to_world.BuildTranslation(target_in_world);
|
|
new_local_to_world.BuildRotation(current_rotation);
|
|
|
|
Check_Object(entity);
|
|
entity->SetNewLocalToParent(new_local_to_world);
|
|
entity->SyncMatrices(true);
|
|
// EntityManager::Instance->RequestPostCollisionExecution(entity);
|
|
Map::Instance->UpdateZone(entity);
|
|
|
|
Check_Object(EntityManager::Instance);
|
|
|
|
if (entity->GetSolidVolume() || entity->GetCollisionMask() == Entity::EditorIsMovingFlag)
|
|
{
|
|
if (entity->IsMultiZone())
|
|
entity->GetElement()->SetCallbackIndex(ElementRenderer::Element::DrawRedBounds);
|
|
else if (entity->IsMultiTile())
|
|
entity->GetElement()->SetCallbackIndex(ElementRenderer::Element::DrawYellowBounds);
|
|
else
|
|
entity->GetElement()->SetCallbackIndex(ElementRenderer::Element::DrawGreenBounds);
|
|
}
|
|
else
|
|
entity->GetElement()->SetCallbackIndex(ElementRenderer::Element::DrawGreenBounds);
|
|
|
|
if (entity->IsDerivedFrom(EditorLatticeNode::DefaultData))
|
|
{
|
|
EditorLatticeNode* node;
|
|
node = Cast_Object(EditorLatticeNode*,entity);
|
|
node->railNode->Location(target_in_world);
|
|
node->railNode->UpdateRadiusPointData();
|
|
}
|
|
else if (entity->IsDerivedFrom(EditorPathNode::DefaultData))
|
|
{
|
|
EditorPathNode* node;
|
|
node = Cast_Object(EditorPathNode*,entity);
|
|
node->pathSlot.GetCurrent()->pathSlot.GetCurrent()->pathPoints[node->index] = target_in_world;
|
|
node->UpdateLinkPointData();
|
|
}
|
|
else if (entity->IsDerivedFrom(EditorBoundaryNode::DefaultData))
|
|
{
|
|
EditorBoundaryNode* node;
|
|
node = Cast_Object(EditorBoundaryNode*,entity);
|
|
|
|
(*node->myBoundary)[node->index].x = target_in_world.x;
|
|
(*node->myBoundary)[node->index].y = target_in_world.z;
|
|
|
|
node->CheckValidPos();
|
|
node->UpdateLinkPointData();
|
|
}
|
|
else if (entity->IsDerivedFrom(EditorDropNode::DefaultData))
|
|
{
|
|
EditorDropNode* node;
|
|
node = Cast_Object(EditorDropNode*,entity);
|
|
node->dropZone->SetNewLocalToParent(new_local_to_world);
|
|
node->dropZone->SyncMatrices(true);
|
|
|
|
EditorDropZonePoint* point;
|
|
LinearMatrix4D matrix = LinearMatrix4D::Identity;
|
|
ChainIteratorOf<EditorDropZonePoint*> iterator(&node->pointChain);
|
|
Point3D newPoint;
|
|
while((point = iterator.ReadAndNext()) != NULL)
|
|
{
|
|
newPoint = new_local_to_world;
|
|
newPoint -= point->offset;
|
|
newPoint.y = theApp.displayWindow->GetMapPointVertical(newPoint.x,newPoint.z);
|
|
matrix.BuildTranslation(newPoint);
|
|
point->SetNewLocalToParent(matrix);
|
|
point->SyncMatrices(true);
|
|
point->UpdateLinkPointData();
|
|
}
|
|
node->UpdatePoints();
|
|
}
|
|
else if (entity->IsDerivedFrom(EditorDropZonePoint::DefaultData))
|
|
{
|
|
EditorDropZonePoint* node;
|
|
node = Cast_Object(EditorDropZonePoint*,entity);
|
|
node->SetNewLocalToParent(new_local_to_world);
|
|
node->SyncMatrices(true);
|
|
node->UpdateLinkPointData();
|
|
|
|
Point3D newPoint;
|
|
newPoint = new_local_to_world;
|
|
node->offset = node->dropNode->GetLocalToWorld();
|
|
node->offset -= newPoint;
|
|
node->dropNode->UpdatePoints();
|
|
}
|
|
/*
|
|
else if (entity->IsDerivedFrom(EditorObjectiveMarker::DefaultData))
|
|
{
|
|
EditorObjectiveMarker* node;
|
|
node = Cast_Object(EditorObjectiveMarker*,entity);
|
|
node->objective->SetNewLocalToParent(new_local_to_world);
|
|
node->objective->SyncMatrices(true);
|
|
}
|
|
*/
|
|
else if (entity->IsDerivedFrom(EditorPointLight::DefaultData) ||
|
|
entity->IsDerivedFrom(EditorSpotLight::DefaultData))
|
|
{
|
|
EditorLight* light;
|
|
light = Cast_Object(EditorLight*,entity);
|
|
|
|
light->SetLightToWorldMatrix(light->GetLocalToWorld());
|
|
}
|
|
|
|
else if (entity->IsDerivedFrom(EditorCameraShip::DefaultData))
|
|
{
|
|
EditorCameraShip* node;
|
|
node = Cast_Object(EditorCameraShip*,entity);
|
|
node->cameraShip->SetNewLocalToParent(new_local_to_world);
|
|
node->cameraShip->SyncMatrices(true);
|
|
}
|
|
|
|
}
|
|
cursorPosition = translation;
|
|
}
|
|
theApp.MakeObjectsTileBased();
|
|
}
|