123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122 |
- #include "qedefs.h"
- id map_i;
- @implementation Map
- /*
- ===============================================================================
- FILE METHODS
- ===============================================================================
- */
- - init
- {
- [super init];
- map_i = self;
- minz = 0;
- maxz = 80;
-
- oldselection = [[List alloc] init];
-
- return self;
- }
- - saveSelected
- {
- int i, c;
- id o, w;
-
- [oldselection empty];
- w = [self objectAt: 0];
- c = [w count];
- sb_newowner = oldselection;
- for (i=0 ; i<c ; i++)
- {
- o = [w objectAt: 0];
- if ([o selected])
- [o moveToEntity];
- else
- {
- [w removeObjectAt: 0];
- [o free];
- }
- }
-
- c = [self count];
- for (i=0 ; i<c ; i++)
- {
- o = [self objectAt: 0];
- [self removeObjectAt: 0];
- [o freeObjects];
- [o free];
- }
- return self;
- }
- - addSelected
- {
- int i, c;
- id n, w;
-
- c = [oldselection count];
- w = [self objectAt: 0]; // world object
- sb_newowner = w;
- for (i=0 ; i<c ; i++)
- {
- n = [oldselection objectAt:i];
- [n moveToEntity];
- i--;
- c--;
- }
- [oldselection empty];
-
- return self;
- }
- - newMap
- {
- id ent;
-
- [self saveSelected];
- ent = [[Entity alloc] initClass: "worldspawn"];
- [self addObject: ent];
- currentEntity = NULL;
- [self setCurrentEntity: ent];
- [self addSelected];
- return self;
- }
- - currentEntity
- {
- return currentEntity;
- }
- - setCurrentEntity: ent
- {
- id old;
-
- old = currentEntity;
- currentEntity = ent;
- if (old != ent)
- {
- [things_i newCurrentEntity]; // update inspector
- [inspcontrol_i changeInspectorTo:i_things];
- }
-
- return self;
- }
- - (float)currentMinZ
- {
- float grid;
-
- grid = [xyview_i gridsize];
- minz = grid * rint(minz/grid);
- return minz;
- }
- - setCurrentMinZ: (float)m
- {
- if (m > -2048)
- minz = m;
- return self;
- }
- - (float)currentMaxZ
- {
- float grid;
-
- [self currentMinZ]; // grid align
-
- grid = [xyview_i gridsize];
- maxz = grid * rint(maxz/grid);
- if (maxz <= minz)
- maxz = minz + grid;
- return maxz;
- }
- - setCurrentMaxZ: (float)m
- {
- if (m < 2048)
- maxz = m;
- return self;
- }
- - removeObject: o
- {
- o = [super removeObject: o];
-
- if (o == currentEntity)
- { // select the world
- [self setCurrentEntity: [self objectAt: 0]];
- }
- return o;
- }
- - writeStats
- {
- FILE *f;
- extern int c_updateall;
- struct timeval tp;
- struct timezone tzp;
- gettimeofday(&tp, &tzp);
-
- f = fopen (FN_DEVLOG, "a");
- fprintf (f,"%i %i\n", (int)tp.tv_sec, c_updateall);
- c_updateall = 0;
- fclose (f);
- return self;
- }
- - (int)numSelected
- {
- int i, c;
- int num;
-
- num = 0;
- c = [currentEntity count];
- for (i=0 ; i<c ; i++)
- if ( [[currentEntity objectAt: i] selected] )
- num++;
- return num;
- }
- - selectedBrush
- {
- int i, c;
- int num;
-
- num = 0;
- c = [currentEntity count];
- for (i=0 ; i<c ; i++)
- if ( [[currentEntity objectAt: i] selected] )
- return [currentEntity objectAt: i];
- return nil;
- }
- /*
- =================
- readMapFile
- =================
- */
- - readMapFile: (char *)fname
- {
- char *dat, *cl;
- id new;
- id ent;
- int i, c;
- vec3_t org;
- float angle;
-
- [self saveSelected];
-
- qprintf ("loading %s\n", fname);
- LoadFile (fname, (void **)&dat);
- StartTokenParsing (dat);
- do
- {
- new = [[Entity alloc] initFromTokens];
- if (!new)
- break;
- [self addObject: new];
- } while (1);
- free (dat);
- [self setCurrentEntity: [self objectAt: 0]];
- [self addSelected];
-
- // load the apropriate texture wad
- dat = [currentEntity valueForQKey: "wad"];
- if (dat && dat[0])
- {
- if (dat[0] == '/') // remove old style fullpaths
- [currentEntity removeKeyPair: "wad"];
- else
- {
- if (strcmp ([texturepalette_i currentWad], dat) )
- [project_i setTextureWad: dat];
- }
- }
- // center the camera and XY view on the playerstart
- c = [self count];
- for (i=1 ; i<c ; i++)
- {
- ent = [self objectAt: i];
- cl = [ent valueForQKey: "classname"];
- if (cl && !strcasecmp (cl,"info_player_start"))
- {
- angle = atof( [ent valueForQKey: "angle"] );
- angle = angle/180*M_PI;
- [ent getVector: org forKey: "origin"];
- [cameraview_i setOrigin: org angle:angle];
- [xyview_i centerOn: org];
- break;
- }
- }
-
- return self;
- }
- /*
- =================
- writeMapFile
- =================
- */
- - writeMapFile: (char *)fname useRegion: (BOOL)reg
- {
- FILE *f;
- int i;
-
- qprintf ("writeMapFile: %s", fname);
-
- f = fopen (fname,"w");
- if (!f)
- Error ("couldn't write %s", fname);
-
- for (i=0 ; i<numElements ; i++)
- [[self objectAt: i] writeToFILE: f region: reg];
-
- fclose (f);
-
- return self;
- }
- /*
- ==============================================================================
- DRAWING
- ==============================================================================
- */
- - ZDrawSelf
- {
- int i, count;
-
- count = [self count];
- for (i=0 ; i<count ; i++)
- [[self objectAt: i] ZDrawSelf];
- return self;
- }
- - RenderSelf: (void (*) (face_t *))callback
- {
- int i, count;
-
- count = [self count];
- for (i=0 ; i<count ; i++)
- [[self objectAt: i] RenderSelf: callback];
- return self;
- }
- //============================================================================
- /*
- ===================
- entityConnect
- A command-shift-click on an entity while an entity is selected will
- make a target connection from the original entity.
- ===================
- */
- - entityConnect: (vec3_t)p1 : (vec3_t)p2
- {
- id oldent, ent;
-
- oldent = [self currentEntity];
- if (oldent == [self objectAt: 0])
- {
- qprintf ("Must have a non-world entity selected to connect");
- return self;
- }
- [self selectRay: p1 : p2 : YES];
- ent = [self currentEntity];
- if (ent == oldent)
- {
- qprintf ("Must click on a different entity to connect");
- return self;
- }
-
- if (ent == [self objectAt: 0])
- {
- qprintf ("Must click on a non-world entity to connect");
- return self;
- }
-
- [oldent setKey:"target" toValue: [ent targetname]];
- [quakeed_i updateAll];
- return self;
- }
- /*
- =================
- selectRay
- If ef is true, any entity brush along the ray will be selected in preference
- to intervening world brushes
- =================
- */
- - selectRay: (vec3_t)p1 : (vec3_t)p2 : (BOOL)ef
- {
- int i, j, c, c2;
- id ent, bestent;
- id brush, bestbrush;
- int face, bestface;
- float time, besttime;
- texturedef_t *td;
-
- bestent = nil;
- bestface = -1;
- bestbrush = nil;
- besttime = 99999;
-
- c = [self count];
- for (i=c-1 ; i>=0 ; i--)
- {
- ent = [self objectAt: i];
- c2 = [ent count];
- for (j=0 ; j<c2 ; j++)
- {
- brush = [ent objectAt: j];
- [brush hitByRay: p1 : p2 : &time : &face];
- if (time < 0 || time >besttime)
- continue;
- bestent = ent;
- besttime = time;
- bestbrush = brush;
- bestface = face;
- }
- if (i == 1 && ef && bestbrush)
- break; // found an entity, so don't check the world
- }
-
- if (besttime == 99999)
- {
- qprintf ("trace missed");
- return self;
- }
- if ( [bestbrush regioned] )
- {
- qprintf ("WANRING: clicked on regioned brush");
- return self;
- }
-
- if (bestent != currentEntity)
- {
- [self makeSelectedPerform: @selector(deselect)];
- [self setCurrentEntity: bestent];
- }
-
- [quakeed_i disableFlushWindow];
- if ( ![bestbrush selected] )
- {
- if ( [map_i numSelected] == 0)
- { // don't grab texture if others are selected
- td = [bestbrush texturedefForFace: bestface];
- [texturepalette_i setTextureDef: td];
- }
- [bestbrush setSelected: YES];
- qprintf ("selected entity %i brush %i face %i", [self indexOf:bestent], [bestent indexOf: bestbrush], bestface);
- }
- else
- {
- [bestbrush setSelected: NO];
- qprintf ("deselected entity %i brush %i face %i", [self indexOf:bestent], [bestent indexOf: bestbrush], bestface);
- }
- [quakeed_i reenableFlushWindow];
- [quakeed_i updateAll];
-
- return self;
- }
- /*
- =================
- grabRay
- only checks the selected brushes
- Returns the brush hit, or nil if missed.
- =================
- */
- - grabRay: (vec3_t)p1 : (vec3_t)p2
- {
- int i, j, c, c2;
- id ent;
- id brush, bestbrush;
- int face;
- float time, besttime;
-
- bestbrush = nil;
- besttime = 99999;
-
- c = [self count];
- for (i=0 ; i<c ; i++)
- {
- ent = [self objectAt: i];
- c2 = [ent count];
- for (j=0 ; j<c2 ; j++)
- {
- brush = [ent objectAt: j];
- if (![brush selected])
- continue;
- [brush hitByRay: p1 : p2 : &time : &face];
- if (time < 0 || time >besttime)
- continue;
- besttime = time;
- bestbrush = brush;
- }
- }
-
- if (besttime == 99999)
- return nil;
-
- return bestbrush;
- }
- /*
- =================
- getTextureRay
- =================
- */
- - getTextureRay: (vec3_t)p1 : (vec3_t)p2
- {
- int i, j, c, c2;
- id ent, bestent;
- id brush, bestbrush;
- int face, bestface;
- float time, besttime;
- texturedef_t *td;
- vec3_t mins, maxs;
- bestbrush = nil;
- bestent = nil;
- besttime = 99999;
- bestface = -1;
- c = [self count];
- for (i=0 ; i<c ; i++)
- {
- ent = [self objectAt: i];
- c2 = [ent count];
- for (j=0 ; j<c2 ; j++)
- {
- brush = [ent objectAt: j];
- [brush hitByRay: p1 : p2 : &time : &face];
- if (time < 0 || time >besttime)
- continue;
- bestent = ent;
- bestface = face;
- besttime = time;
- bestbrush = brush;
- }
- }
-
- if (besttime == 99999)
- return nil;
- if ( ![bestent modifiable])
- {
- qprintf ("can't modify spawned entities");
- return self;
- }
-
- td = [bestbrush texturedefForFace: bestface];
- [texturepalette_i setTextureDef: td];
-
- qprintf ("grabbed texturedef and sizes");
-
- [bestbrush getMins: mins maxs: maxs];
-
- minz = mins[2];
- maxz = maxs[2];
-
- return bestbrush;
- }
- /*
- =================
- setTextureRay
- =================
- */
- - setTextureRay: (vec3_t)p1 : (vec3_t)p2 : (BOOL)allsides;
- {
- int i, j, c, c2;
- id ent, bestent;
- id brush, bestbrush;
- int face, bestface;
- float time, besttime;
- texturedef_t td;
-
- bestent = nil;
- bestface = -1;
- bestbrush = nil;
- besttime = 99999;
-
- c = [self count];
- for (i=0 ; i<c ; i++)
- {
- ent = [self objectAt: i];
- c2 = [ent count];
- for (j=0 ; j<c2 ; j++)
- {
- brush = [ent objectAt: j];
- [brush hitByRay: p1 : p2 : &time : &face];
- if (time < 0 || time >besttime)
- continue;
- bestent = ent;
- besttime = time;
- bestbrush = brush;
- bestface = face;
- }
- }
-
- if (besttime == 99999)
- {
- qprintf ("trace missed");
- return self;
- }
- if ( ![bestent modifiable])
- {
- qprintf ("can't modify spawned entities");
- return self;
- }
-
- if ( [bestbrush regioned] )
- {
- qprintf ("WANRING: clicked on regioned brush");
- return self;
- }
-
- [texturepalette_i getTextureDef: &td];
-
- [quakeed_i disableFlushWindow];
- if (allsides)
- {
- [bestbrush setTexturedef: &td];
- qprintf ("textured entity %i brush %i", [self indexOf:bestent], [bestent indexOf: bestbrush]);
- }
- else
- {
- [bestbrush setTexturedef: &td forFace: bestface];
- qprintf ("deselected entity %i brush %i face %i", [self indexOf:bestent], [bestent indexOf: bestbrush], bestface);
- }
- [quakeed_i reenableFlushWindow];
-
- [quakeed_i updateAll];
-
- return self;
- }
- /*
- ==============================================================================
- OPERATIONS ON SELECTIONS
- ==============================================================================
- */
- - makeSelectedPerform: (SEL)sel
- {
- int i,j, c, c2;
- id ent, brush;
- int total;
-
- total = 0;
- c = [self count];
- for (i=c-1 ; i>=0 ; i--)
- {
- ent = [self objectAt: i];
- c2 = [ent count];
- for (j = c2-1 ; j >=0 ; j--)
- {
- brush = [ent objectAt: j];
- if (! [brush selected] )
- continue;
- if ([brush regioned])
- continue;
- total++;
- [brush perform:sel];
- }
- }
- // if (!total)
- // qprintf ("nothing selected");
-
- return self;
- }
- - makeUnselectedPerform: (SEL)sel
- {
- int i,j, c, c2;
- id ent, brush;
-
- c = [self count];
- for (i=c-1 ; i>=0 ; i--)
- {
- ent = [self objectAt: i];
- c2 = [ent count];
- for (j = c2-1 ; j >=0 ; j--)
- {
- brush = [ent objectAt: j];
- if ( [brush selected] )
- continue;
- if ([brush regioned])
- continue;
- [brush perform:sel];
- }
- }
- return self;
- }
- - makeAllPerform: (SEL)sel
- {
- int i,j, c, c2;
- id ent, brush;
-
- c = [self count];
- for (i=c-1 ; i>=0 ; i--)
- {
- ent = [self objectAt: i];
- c2 = [ent count];
- for (j = c2-1 ; j >=0 ; j--)
- {
- brush = [ent objectAt: j];
- if ([brush regioned])
- continue;
- [brush perform:sel];
- }
- }
- return self;
- }
- - makeGlobalPerform: (SEL)sel // in and out of region
- {
- int i,j, c, c2;
- id ent, brush;
-
- c = [self count];
- for (i=c-1 ; i>=0 ; i--)
- {
- ent = [self objectAt: i];
- c2 = [ent count];
- for (j = c2-1 ; j >=0 ; j--)
- {
- brush = [ent objectAt: j];
- [brush perform:sel];
- }
- }
- return self;
- }
- void sel_identity (void)
- {
- sel_x[0]=1; sel_x[1]=0; sel_x[2]=0;
- sel_y[0]=0; sel_y[1]=1; sel_y[2]=0;
- sel_z[0]=0; sel_z[1]=0; sel_z[2]=1;
- }
- - transformSelection
- {
- if ( ![currentEntity modifiable])
- {
- qprintf ("can't modify spawned entities");
- return self;
- }
- // find an origin to apply the transformation to
- sb_mins[0] = sb_mins[1] = sb_mins[2] = 99999;
- sb_maxs[0] = sb_maxs[1] = sb_maxs[2] = -99999;
- [self makeSelectedPerform: @selector(addToBBox)];
- sel_org[0] = [xyview_i snapToGrid: (sb_mins[0] + sb_maxs[0])/2];
- sel_org[1] = [xyview_i snapToGrid: (sb_mins[1] + sb_maxs[1])/2];
- sel_org[2] = [xyview_i snapToGrid: (sb_mins[2] + sb_maxs[2])/2];
-
- // do it!
- [self makeSelectedPerform: @selector(transform)];
- [quakeed_i updateAll];
- return self;
- }
- void swapvectors (vec3_t a, vec3_t b)
- {
- vec3_t temp;
-
- VectorCopy (a, temp);
- VectorCopy (b, a);
- VectorSubtract (vec3_origin, temp, b);
- }
- /*
- ===============================================================================
- UI operations
- ===============================================================================
- */
- - rotate_x: sender
- {
- sel_identity ();
- swapvectors(sel_y, sel_z);
- [self transformSelection];
- return self;
- }
- - rotate_y: sender
- {
- sel_identity ();
- swapvectors(sel_x, sel_z);
- [self transformSelection];
- return self;
- }
- - rotate_z: sender
- {
- sel_identity ();
- swapvectors(sel_x, sel_y);
- [self transformSelection];
- return self;
- }
- - flip_x: sender
- {
- sel_identity ();
- sel_x[0] = -1;
- [self transformSelection];
- [map_i makeSelectedPerform: @selector(flipNormals)];
- return self;
- }
- - flip_y: sender
- {
- sel_identity ();
- sel_y[1] = -1;
- [self transformSelection];
- [map_i makeSelectedPerform: @selector(flipNormals)];
- return self;
- }
- - flip_z: sender
- {
- sel_identity ();
- sel_z[2] = -1;
- [self transformSelection];
- [map_i makeSelectedPerform: @selector(flipNormals)];
- return self;
- }
- - cloneSelection: sender
- {
- int i,j , c, originalElements;
- id o, b;
- id new;
-
- sb_translate[0] = sb_translate[1] = [xyview_i gridsize];
- sb_translate[2] = 0;
- // copy individual brushes in the world entity
- o = [self objectAt: 0];
- c = [o count];
- for (i=0 ; i<c ; i++)
- {
- b = [o objectAt: i];
- if (![b selected])
- continue;
-
- // copy the brush, then translate the original
- new = [b copy];
- [new setSelected: YES];
- [new translate];
- [b setSelected: NO];
- [o addObject: new];
- }
-
- // copy entire entities otherwise
- originalElements = numElements; // don't copy the new ones
- for (i=1 ; i<originalElements ; i++)
- {
- o = [self objectAt: i];
- if (![[o objectAt: 0] selected])
- continue;
- new = [o copy];
- [self addObject: new];
- c = [o count];
- for (j=0 ; j<c ; j++)
- [[o objectAt: j] setSelected: NO];
-
- c = [new count];
- for (j=0 ; j<c ; j++)
- {
- b = [new objectAt: j];
- [b translate];
- [b setSelected: YES];
- }
- }
- [quakeed_i updateAll];
- return self;
- }
- - selectCompleteEntity: sender
- {
- id o;
- int i, c;
-
- o = [self selectedBrush];
- if (!o)
- {
- qprintf ("nothing selected");
- return self;
- }
- o = [o parent];
- c = [o count];
- for (i=0 ; i<c ; i++)
- [[o objectAt: i] setSelected: YES];
- qprintf ("%i brushes selected", c);
- [quakeed_i updateAll];
- return self;
- }
- - makeEntity: sender
- {
- if (currentEntity != [self objectAt: 0])
- {
- qprintf ("ERROR: can't makeEntity inside an entity");
- NXBeep ();
- return self;
- }
-
- if ( [self numSelected] == 0)
- {
- qprintf ("ERROR: must have a seed brush to make an entity");
- NXBeep ();
- return self;
- }
-
- sb_newowner = [[Entity alloc] initClass: [things_i spawnName]];
- if ( [sb_newowner modifiable] )
- [self makeSelectedPerform: @selector(moveToEntity)];
- else
- { // throw out seed brush and select entity fixed brush
- [self makeSelectedPerform: @selector(remove)];
- [[sb_newowner objectAt: 0] setSelected: YES];
- }
-
- [self addObject: sb_newowner];
- [self setCurrentEntity: sb_newowner];
-
- [quakeed_i updateAll];
-
- return self;
- }
- - selbox: (SEL)selector
- {
- id b;
-
- if ([self numSelected] != 1)
- {
- qprintf ("must have a single brush selected");
- return self;
- }
- b = [self selectedBrush];
- [b getMins: select_min maxs: select_max];
- [b remove];
-
- [self makeUnselectedPerform: selector];
-
- qprintf ("identified contents");
- [quakeed_i updateAll];
-
- return self;
- }
- - selectCompletelyInside: sender
- {
- return [self selbox: @selector(selectComplete)];
- }
- - selectPartiallyInside: sender
- {
- return [self selbox: @selector(selectPartial)];
- }
- - tallBrush: sender
- {
- id b;
- vec3_t mins, maxs;
- texturedef_t td;
-
- if ([self numSelected] != 1)
- {
- qprintf ("must have a single brush selected");
- return self;
- }
- b = [self selectedBrush];
- td = *[b texturedef];
- [b getMins: mins maxs: maxs];
- [b remove];
- mins[2] = -2048;
- maxs[2] = 2048;
-
- b = [[SetBrush alloc] initOwner: [map_i objectAt:0] mins: mins maxs: maxs texture: &td];
- [[map_i objectAt: 0] addObject: b];
- [b setSelected: YES];
- [quakeed_i updateAll];
-
- return self;
- }
- - shortBrush: sender
- {
- id b;
- vec3_t mins, maxs;
- texturedef_t td;
-
- if ([self numSelected] != 1)
- {
- qprintf ("must have a single brush selected");
- return self;
- }
- b = [self selectedBrush];
- td = *[b texturedef];
- [b getMins: mins maxs: maxs];
- [b remove];
- mins[2] = 0;
- maxs[2] = 16;
-
- b = [[SetBrush alloc] initOwner: [map_i objectAt:0] mins: mins maxs: maxs texture: &td];
- [[map_i objectAt: 0] addObject: b];
- [b setSelected: YES];
- [quakeed_i updateAll];
-
- return self;
- }
- /*
- ==================
- subtractSelection
- ==================
- */
- - subtractSelection: semder
- {
- int i, j, c, c2;
- id o, o2;
- id sellist, sourcelist;
-
- qprintf ("performing brush subtraction...");
- sourcelist = [[List alloc] init];
- sellist = [[List alloc] init];
- carve_in = [[List alloc] init];
- carve_out = [[List alloc] init];
-
- c = [currentEntity count];
- for (i=0 ; i<c ; i++)
- {
- o = [currentEntity objectAt: i];
- if ([o selected])
- [sellist addObject: o];
- else
- [sourcelist addObject: o];
- }
-
-
- c = [sellist count];
- for (i=0 ; i<c ; i++)
- {
- o = [sellist objectAt: i];
- [o setCarveVars];
-
- c2 = [sourcelist count];
- for (j=0 ; j<c2 ; j++)
- {
- o2 = [sourcelist objectAt: j];
- [o2 carve];
- [carve_in freeObjects];
- }
- [sourcelist free]; // the individual have been moved/freed
- sourcelist = carve_out;
- carve_out = [[List alloc] init];
- }
- // add the selection back to the remnants
- [currentEntity empty];
- [currentEntity appendList: sourcelist];
- [currentEntity appendList: sellist];
- [sourcelist free];
- [sellist free];
- [carve_in free];
- [carve_out free];
-
- if (![currentEntity count])
- {
- o = currentEntity;
- [self removeObject: o];
- [o free];
- }
- qprintf ("subtracted selection");
- [quakeed_i updateAll];
-
- return self;
- }
- @end
|