/*
* 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/Group.cpp $
* $Revision: 1.1.1.1 $
* $Date: 2003-08-26 03:57:38 $
* $Author: kevinb $
*
* Functions for copying, pasting, etc. of groups
*
* $Log: not supported by cvs2svn $
*
* 35 9/15/99 1:56p Matt
* Added the option to allow rooms or groups placed on the terrain to
* either align with the terrain or with gravity.
*
* 34 8/30/99 1:01p Gwar
* use the "true" center of faces for determining place position of a
* group
*
* 33 8/17/99 6:12p Gwar
* handle NEWEDITOR generic object management in AttachGroup
*
* 32 8/17/99 6:46a Gwar
* added group support to NEWEDITOR
*
* 31 5/08/99 1:39a Matt
* Added a function to delete all objects of a certain type, and support
* for placing and attaching groups to the terrain.
*
* 30 4/21/99 10:19p Matt
* DeleteGroup() wasn't setting the world changed flag
*
* 29 3/15/99 1:29p Matt
* Added objects & triggers to save/load for groups.
*
* 28 1/29/99 12:48p Matt
* Rewrote the doorway system
*
* 27 1/26/99 6:02p Matt
* Fixed (I hope) a problem with pasted object having the wrong
* orientation.
*
* 26 1/21/99 11:15p Jeff
* pulled out some structs and defines from header files and moved them
* into separate header files so that multiplayer dlls don't require major
* game headers, just those new headers. Side effect is a shorter build
* time. Also cleaned up some header file #includes that weren't needed.
* This affected polymodel.h, object.h, player.h, vecmat.h, room.h,
* manage.h and multi.h
*
* 25 1/21/99 11:34a Matt
* Got rid of portal triggers. Since we don't have multi-face portals, a
* face trigger works fine for a portal. Also fixed a few editor/trigger
* bugs.
*
* 24 1/14/99 11:06a Matt
* Added names to triggers
*
* 23 1/08/99 2:56p Samir
* Ripped out OSIRIS1.
*
* 22 12/01/98 11:17p Matt
* Made copy/paste work with doors.
*
* 21 10/08/98 4:23p Kevin
* Changed code to comply with memory library usage. Always use mem_malloc
* , mem_free and mem_strdup
*
* 20 9/24/98 5:00p Matt
* Improved error checking for running out of rooms.
*
* 19 9/02/98 5:57p Matt
* Added code to make faces match exactly when forming a portal. This
* should get rid of all remaining cracking problems.
*
* 18 9/01/98 12:04p Matt
* Ripped out multi-face portal code
*
* 17 8/15/98 10:50p Matt
* When copying a portal, copy its flags
*
* 16 6/23/98 2:43p Matt
* Changed calls to OutrageMessageBox() & Debug_MessageBox() to deal with
* int return value (instead of bool).
*
* 15 4/21/98 2:43p Matt
* Added system to disable render updates while deleting large numbers of
* rooms, since the mine is not stable until this operation is done.
*
* 14 2/09/98 1:38p Matt
* When pasting a group, ask the user if he also wants to paste objects
* and triggers
*
* 13 2/04/98 6:23p Matt
* Changed object room number to indicate a terrain cell via a flag. Got
* rid of the object flag which used to indicate terrain.
*
* 12 1/29/98 5:50p Matt
* Changed old camera object type to be viewer object (for editor), and
* now camera objects will just be for game cameras.
*
* 11 1/20/98 4:12p Samir
* New script housekeeping system.
*
* 10 1/15/98 7:34p Matt
* Revamped error checking when computing face normals
*
* 9 12/23/97 11:06a Samir
* Added pserror.h
*
* 8 10/13/97 6:20p Matt
* Fixed stupid bug copying objects in group
*
* 7 10/03/97 3:37p Matt
* Fixed bug copying multiple objects in a room, and changed code to not
* copy viewer or player objects
*
* 6 9/24/97 6:18p Samir
* Use script names instead of script id values to identify scripts.
*
* 5 9/22/97 2:31p Matt
* Made group code copy & paste objects & triggers
*
* 4 9/08/97 4:05p Samir
* Fixed some warnings and took out extranneous includes to windows.h in
* important headers.
*
* 3 9/02/97 6:42p Matt
* Got paste & group save/load working
*
* 2 8/29/97 5:45p Matt
* Converted group code to work with rooms (unfinished)
*
* 11 6/16/97 6:40p Matt
* Fixed bug caused when Selected_segments[] was changed while
* DeleteGroup() was indexing through it.
*
* 10 6/12/97 7:17p Matt
* Deleted now-unused RotateWorld() function
*
* 9 5/23/97 5:46p Matt
* Added SetMatrixBasedOnSide() functionality to ExtractMatrixFromSeg().
*
* 8 5/13/97 11:58a Matt
* Made group file code save & load the level file version number to use
* when reading segments
*
* 7 5/08/97 5:07p Matt
* When rotating world, rotate the editor's wireframe window view vars
*
* 6 5/08/97 4:43p Matt
* Fixed bug when rotating objects in RotateWorld()
*
* 5 5/06/97 2:26p Jason
* fixed bug in rotate world
*
* 4 5/05/97 3:57p Matt
* Added code to rotate the mine (& the objects in it) to join with the
* terrain.
*
* 3 3/31/97 5:58p Matt
* Revamped mine update flags
*
* 2 3/12/97 3:25p Matt
* Added funcs for cut, copy, paste, & delete, and to save and load
* groups.
*
* 1 3/11/97 9:34p Matt
*
* $NoKeywords: $
*/
#include "group.h"
#ifndef NEWEDITOR
#include "d3edit.h"
#else
#include "globals.h"
#endif
#include "selectedroom.h"
#include "room.h"
#include "hroom.h"
#include "erooms.h"
#include "loadlevel.h"
#ifndef NEWEDITOR
#include "moveworld.h"
#endif
#include "object.h"
#include "trigger.h"
#include "pserror.h"
#include "doorway.h"
#include "mem.h"
#include
#include "door.h"
// Free a group.
// Parameters: g - the group to be freed
void FreeGroup(group *g) {
for (int r = 0; r < g->nrooms; r++)
FreeRoom(&g->rooms[r]);
mem_free(g->rooms);
if (g->nobjects)
mem_free(g->objects);
if (g->ntriggers)
mem_free(g->triggers);
mem_free(g);
}
// Copy the given list of rooms to a group
// Parameters: nrooms - the number of rooms in list
// roomnums - pointer to list of room numbers
// attachroom, attachface - where group attaches when pasted
// Returns: pointer to group
group *CopyGroup(int nrooms, int *roomnums, int attachroom, int attachface) {
int r;
int room_xlate[MAX_ROOMS];
int n_objects = 0, n_triggers = 0, n_doors = 0;
// Allocate group & room arrays
auto g = mem_rmalloc();
ASSERT(g != NULL);
g->nrooms = nrooms;
g->rooms = mem_rmalloc(nrooms);
ASSERT(g->rooms != NULL);
// Initialize xlate list
for (r = 0; r < MAX_ROOMS; r++)
room_xlate[r] = -1;
// Copy the rooms & build xlate list. Count objects while we're at it
for (r = 0; r < nrooms; r++) {
CopyRoom(&g->rooms[r], &Rooms[roomnums[r]]);
room_xlate[roomnums[r]] = r;
for (int o = Rooms[roomnums[r]].objects; o != -1; o = Objects[o].next)
if ((Objects[o].type != OBJ_VIEWER) && (Objects[o].type != OBJ_CAMERA) && (Objects[o].type != OBJ_PLAYER)) {
n_objects++;
if (Objects[o].type == OBJ_DOOR)
n_doors++;
}
}
// Add portals for rooms in the group
for (r = 0; r < nrooms; r++)
for (int p = 0; p < Rooms[roomnums[r]].num_portals; p++) {
portal *pp = &Rooms[roomnums[r]].portals[p];
if ((pp->croom != -1) && IsRoomSelected(pp->croom)) {
// link the two rooms
if (r < room_xlate[pp->croom]) // only link lower to higher, so we don't double link
LinkRoomsSimple(g->rooms, r, pp->portal_face, room_xlate[pp->croom],
Rooms[pp->croom].portals[pp->cportal].portal_face);
// Copy the portal flags
int new_portal_num = g->rooms[r].faces[pp->portal_face].portal_num;
g->rooms[r].portals[new_portal_num].flags = pp->flags;
}
}
// Fill in attach fields
g->attachroom = room_xlate[attachroom];
g->attachface = attachface;
// Copy objects
g->nobjects = n_objects;
g->ndoors = n_doors;
if (n_objects == 0)
g->objects = NULL;
else {
int objnum = 0;
// Get memory for objects
g->objects = mem_rmalloc