#include "QF/dstring.h" #include "QF/script.h" #include "QF/sys.h" #include "Entity.h" #include "EntityClass.h" #include "TexturePalette.h" #include "SetBrush.h" #include "Map.h" #include "CameraView.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; } - 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; } - (void)dealloc { epair_t *e, *n; for (e=epairs ; e ; e=n) { n = e->next; free (e->key); free (e->value); free (e); } [super dealloc]; } - (BOOL)modifiable { return modifiable; } - setModifiable: (BOOL)m { modifiable = m; return self; } - (void)removeObject: o { [super removeObject: o]; if ([self count]) return; // the entity is empty, so remove the entire thing if ( self == [map_i objectAtIndex: 0]) return; // never remove the world [map_i removeObject: self]; [self release]; } - (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:(const char *)k toValue:(const char *)v { epair_t *e; 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)) { free (e->value); e->value = strdup (v); return self; } } e = malloc (sizeof(epair_t)); e->key = strdup (k); e->value = strdup (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 count = [map_i count]; maxt = 0; for (i=1 ; i 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; - initFromScript: (script_t *) script { char *key; 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 (!Script_GetToken (script, true)) { [self dealloc]; return nil; } if (strcmp (Script_Token (script), "{") ) Sys_Error ("initFromFileP: { not found"); do { if (!Script_GetToken (script, true)) break; if (!strcmp (Script_Token (script), "}") ) break; if (!strcmp (Script_Token (script), "{") ) { // read a brush brush = [[SetBrush alloc] initFromScript: script owner:self]; [self addObject: brush]; } else { // read a key / value pair key = strdup (Script_Token (script)); Script_GetToken (script, false); [self setKey: key toValue:Script_Token (script)]; free (key); } } 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 removeAllObjects]; } 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 ; inext) fprintf (f,"\"%s\"\t\"%s\"\n", e->key, e->value); // fixed size entities don't save out brushes if ( modifiable ) { for (i = 0 ; i < [self count]; i++) [[self objectAtIndex: i] writeToFILE: f region: reg]; } fprintf (f,"}\n"); if (temporg) [self setKey: "angle" toValue: oldang]; return self; } /* ============================================================================== INTERACTION ============================================================================== */ @end