123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486 |
- #include "qedefs.h"
- @implementation Entity
- vec3_t bad_mins = {-8, -8, -8};
- vec3_t bad_maxs = {8, 8, 8};
- - createFixedBrush: (vec3_t)org
- {
- vec3_t emins, emaxs;
- float *v, *v2, *color;
- id new;
- texturedef_t td;
-
- // get class
- new = [entity_classes_i classForName: [self valueForQKey: "classname"]];
- if (new)
- {
- v = [new mins];
- v2 = [new maxs];
- }
- else
- {
- v = bad_mins;
- v2 = bad_maxs;
- }
- color = [new drawColor];
- modifiable = NO;
- memset(&td,0,sizeof(td));
- strcpy (td.texture,"entity");
- VectorAdd (org, v, emins);
- VectorAdd (org, v2, emaxs);
- new = [[SetBrush alloc] initOwner: self mins:emins maxs:emaxs
- texture: &td];
- [new setEntityColor: color];
- [self addObject: new];
-
- return self;
- }
- - copyFromZone:(NXZone *)zone
- {
- id new, nb;
- epair_t *e;
- int i;
-
- new = [[Entity alloc] init];
- [new setModifiable: modifiable];
-
- for (e=epairs ; e ; e=e->next)
- { // don't copy target and targetname fields
- if (strncmp(e->key,"target",6))
- [new setKey: e->key toValue: e->value];
- }
- for (i=0 ; i<numElements ; i++)
- {
- nb = [[self objectAt: i] copy];
- [nb setParent: new];
- [new addObject: nb];
- }
-
- return new;
- }
- - initClass: (char *)classname
- {
- id new;
- esize_t esize;
- char value[80];
- vec3_t min, max;
- float *v;
-
- [super init];
-
- modifiable = YES;
- [self setKey: "classname" toValue:classname];
- // get class
- new = [entity_classes_i classForName: [self valueForQKey: "classname"]];
- if (!new)
- esize = esize_model;
- else
- esize = [new esize];
-
- // create a brush if needed
- if (esize == esize_fixed)
- {
- v = [new mins];
- [[map_i selectedBrush] getMins: min maxs: max];
- VectorSubtract (min, v, min);
-
- sprintf (value, "%i %i %i",(int)min[0], (int)min[1], (int)min[2]);
- [self setKey:"origin" toValue: value];
- [self createFixedBrush: min];
- }
- else
- modifiable = YES;
-
- return self;
- }
- - free
- {
- epair_t *e, *n;
-
- for (e=epairs ; e ; e=n)
- {
- n = e->next;
- free (e);
- }
- return [super free];
- }
- - (BOOL)modifiable
- {
- return modifiable;
- }
- - setModifiable: (BOOL)m
- {
- modifiable = m;
- return self;
- }
- - removeObject: o
- {
- o = [super removeObject: o];
- if (numElements)
- return o;
- // the entity is empty, so remove the entire thing
- if ( self == [map_i objectAt: 0])
- return o; // never remove the world
-
- [map_i removeObject: self];
- [self free];
- return o;
- }
- - (char *)valueForQKey: (char *)k
- {
- epair_t *e;
- static char ret[64];
-
- for (e=epairs ; e ; e=e->next)
- if (!strcmp(k,e->key))
- {
- strcpy (ret, e->value);
- return ret;
- }
- return "";
- }
- - getVector: (vec3_t)v forKey: (char *)k
- {
- char *c;
-
- c = [self valueForQKey: k];
- v[0] = v[1] = v[2] = 0;
-
- sscanf (c, "%f %f %f", &v[0], &v[1], &v[2]);
- return self;
- }
- - print
- {
- epair_t *e;
-
- for (e=epairs ; e ; e=e->next)
- printf ("%20s : %20s\n",e->key, e->value);
- return self;
- }
- - setKey:(char *)k toValue:(char *)v
- {
- epair_t *e;
- if (strlen(k) > MAX_KEY)
- Error ("setKey: %s > MAX_KEY", k);
- if (strlen(v) > MAX_VALUE)
- Error ("setKey: %s > MAX_VALUE", v);
-
- while (*k && *k <= ' ')
- k++;
- if (!*k)
- return self; // don't set NULL values
-
- for (e=epairs ; e ; e=e->next)
- if (!strcmp(k,e->key))
- {
- memset (e->value, 0, sizeof(e->value));
- strcpy (e->value, v);
- return self;
- }
- e = malloc (sizeof(epair_t));
- memset (e, 0, sizeof(epair_t));
-
- strcpy (e->key, k);
- strcpy (e->value, v);
- e->next = epairs;
- epairs = e;
-
- return self;
- }
- - (int)numPairs
- {
- int i;
- epair_t *e;
-
- i=0;
- for (e=epairs ; e ; e=e->next)
- i++;
- return i;
- }
- - (epair_t *)epairs
- {
- return epairs;
- }
- - removeKeyPair: (char *)key
- {
- epair_t *e, *e2;
-
- if (!epairs)
- return self;
- e = epairs;
- if (!strcmp(e->key, key))
- {
- epairs = e->next;
- free (e);
- return self;
- }
-
- for (; e ; e=e->next)
- {
- if (e->next && !strcmp(e->next->key, key))
- {
- e2 = e->next;
- e->next = e2->next;
- free (e2);
- return self;
- }
- }
-
- printf ("WARNING: removeKeyPair: %s not found\n", key);
- return self;
- }
- /*
- =============
- targetname
- If the entity does not have a "targetname" key, a unique one is generated
- =============
- */
- - (char *)targetname
- {
- char *t;
- int i, count;
- id ent;
- int tval, maxt;
- char name[20];
-
- t = [self valueForQKey: "targetname"];
- if (t && t[0])
- return t;
-
- // make a unique name of the form t<number>
- count = [map_i count];
- maxt = 0;
- for (i=1 ; i<count ; i++)
- {
- ent = [map_i objectAt: i];
- t = [ent valueForQKey: "targetname"];
- if (!t || t[0] != 't')
- continue;
- tval = atoi (t+1);
- if (tval > maxt)
- maxt = tval;
- }
-
- sprintf (name,"t%i",maxt+1);
-
- [self setKey: "targetname" toValue: name];
-
- return [self valueForQKey: "targetname"]; // so it's not on the stack
- }
- /*
- ==============================================================================
- FILE METHODS
- ==============================================================================
- */
- int nument;
- - initFromTokens
- {
- char key[MAXTOKEN];
- id eclass, brush;
- char *spawn;
- vec3_t emins, emaxs;
- vec3_t org;
- texturedef_t td;
- esize_t esize;
- int i, c;
- float *color;
-
- [self init];
- if (!GetToken (true))
- {
- [self free];
- return nil;
- }
- if (strcmp (token, "{") )
- Error ("initFromFileP: { not found");
-
- do
- {
- if (!GetToken (true))
- break;
- if (!strcmp (token, "}") )
- break;
- if (!strcmp (token, "{") )
- { // read a brush
- brush = [[SetBrush alloc] initFromTokens: self];
- [self addObject: brush];
- }
- else
- { // read a key / value pair
- strcpy (key, token);
- GetToken (false);
- [self setKey: key toValue:token];
- }
- } while (1);
-
- nument++;
- // get class
- spawn = [self valueForQKey: "classname"];
- eclass = [entity_classes_i classForName: spawn];
- esize = [eclass esize];
- [self getVector: org forKey: "origin"];
-
- if ([self count] && esize != esize_model)
- {
- printf ("WARNING:Entity with brushes and wrong model type\n");
- [self empty];
- }
-
- if (![self count] && esize == esize_model)
- {
- printf ("WARNING:Entity with no brushes and esize_model\n");
- [texturepalette_i getTextureDef: &td];
- for (i=0 ; i<3 ; i++)
- {
- emins[i] = org[i] - 8;
- emaxs[i] = org[i] + 8;
- }
- brush = [[SetBrush alloc] initOwner: self mins:emins maxs:emaxs
- texture: &td];
- [self addObject: brush];
- }
-
- // create a brush if needed
- if (esize == esize_fixed)
- [self createFixedBrush: org];
- else
- modifiable = YES;
- // set all the brush colors
- color = [eclass drawColor];
- c = [self count];
- for (i=0 ; i<c ; i++)
- {
- brush = [self objectAt: i];
- [brush setEntityColor: color];
- }
-
- return self;
- }
- - writeToFILE: (FILE *)f region:(BOOL)reg;
- {
- epair_t *e;
- int i;
- id new;
- char value[80];
- vec3_t mins, maxs, org;
- float *v;
- BOOL temporg;
- char oldang[80];
-
- temporg = NO;
- if (reg)
- {
- if ( !strcmp ([self valueForQKey: "classname"], "info_player_start") )
- { // move the playerstart temporarily to the camera position
- temporg = YES;
- strcpy (oldang, [self valueForQKey: "angle"]);
- sprintf (value, "%i", (int)([cameraview_i yawAngle]*180/M_PI));
- [self setKey: "angle" toValue: value];
- }
- else if ( self != [map_i objectAt: 0]
- && [[self objectAt: 0] regioned] )
- return self; // skip the entire entity definition
- }
-
- fprintf (f,"{\n");
- // set an origin epair
- if (!modifiable)
- {
- [[self objectAt: 0] getMins: mins maxs: maxs];
- if (temporg)
- {
- [cameraview_i getOrigin: mins];
- mins[0] -= 16;
- mins[1] -= 16;
- mins[2] -= 48;
- }
- new = [entity_classes_i classForName:
- [self valueForQKey: "classname"]];
- if (new)
- v = [new mins];
- else
- v = vec3_origin;
-
- VectorSubtract (mins, v, org);
- sprintf (value, "%i %i %i",(int)org[0], (int)org[1], (int)org[2]);
- [self setKey:"origin" toValue: value];
- }
-
- for (e=epairs ; e ; e=e->next)
- fprintf (f,"\"%s\"\t\"%s\"\n", e->key, e->value);
-
- // fixed size entities don't save out brushes
- if ( modifiable )
- {
- for (i=0 ; i<numElements ; i++)
- [[self objectAt: i] writeToFILE: f region: reg];
- }
-
- fprintf (f,"}\n");
-
- if (temporg)
- [self setKey: "angle" toValue: oldang];
- return self;
- }
- /*
- ==============================================================================
- INTERACTION
- ==============================================================================
- */
- @end
|