Files
firestorm/Gameleap/code/mw4/Code/MW4GameEd/MoveCommand.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

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();
}