home *** CD-ROM | disk | FTP | other *** search
/ Superpower (Alt) / SUPERPOWER.iso / q / source / entity.m < prev    next >
Encoding:
Text File  |  1996-08-08  |  8.0 KB  |  486 lines

  1.  
  2. #include "qedefs.h"
  3.  
  4. @implementation Entity
  5.  
  6. vec3_t bad_mins = {-8, -8, -8};
  7. vec3_t bad_maxs = {8, 8, 8};
  8.  
  9. - createFixedBrush: (vec3_t)org
  10. {
  11.     vec3_t    emins, emaxs;
  12.     float    *v, *v2, *color;
  13.     id        new;
  14.     texturedef_t    td;
  15.     
  16. // get class
  17.     new = [entity_classes_i classForName: [self valueForQKey: "classname"]];
  18.     if (new)
  19.     {
  20.         v = [new mins];
  21.         v2 = [new maxs];
  22.     }
  23.     else
  24.     {
  25.         v = bad_mins;
  26.         v2 = bad_maxs;
  27.     }
  28.  
  29.     color = [new drawColor];
  30.  
  31.     modifiable = NO;
  32.     memset(&td,0,sizeof(td));
  33.     strcpy (td.texture,"entity");
  34.  
  35.     VectorAdd (org, v, emins);
  36.     VectorAdd (org, v2, emaxs);
  37.     new = [[SetBrush alloc] initOwner: self mins:emins maxs:emaxs
  38.         texture: &td];
  39.     [new setEntityColor: color];
  40.  
  41.     [self addObject: new];
  42.     
  43.     return self;
  44. }
  45.  
  46. - copyFromZone:(NXZone *)zone
  47. {
  48.     id    new, nb;
  49.     epair_t    *e;
  50.     int    i;
  51.         
  52.     new = [[Entity alloc] init];
  53.     [new setModifiable: modifiable];
  54.     
  55.     for (e=epairs ; e ; e=e->next)
  56.     {    // don't copy target and targetname fields
  57.         if (strncmp(e->key,"target",6))
  58.             [new setKey: e->key toValue: e->value];
  59.     }
  60.  
  61.     for (i=0 ; i<numElements ; i++)
  62.     {
  63.         nb = [[self objectAt: i] copy];
  64.         [nb setParent: new];
  65.         [new addObject: nb];
  66.     }
  67.     
  68.     return new;
  69. }
  70.  
  71. - initClass: (char *)classname
  72. {
  73.     id        new;
  74.     esize_t    esize;
  75.     char    value[80];
  76.     vec3_t    min, max;
  77.     float    *v;
  78.     
  79.     [super init];
  80.     
  81.     modifiable = YES;
  82.  
  83.     [self setKey: "classname" toValue:classname];
  84.  
  85. // get class
  86.     new = [entity_classes_i classForName: [self valueForQKey: "classname"]];
  87.     if (!new)
  88.         esize = esize_model;
  89.     else
  90.         esize = [new esize];
  91.     
  92. // create a brush if needed
  93.     if (esize == esize_fixed)
  94.     {
  95.         v = [new mins];
  96.         [[map_i selectedBrush] getMins: min maxs: max];    
  97.         VectorSubtract (min, v, min);
  98.     
  99.         sprintf (value, "%i %i %i",(int)min[0], (int)min[1], (int)min[2]);
  100.         [self setKey:"origin" toValue: value];
  101.  
  102.         [self createFixedBrush: min];
  103.     }
  104.     else
  105.         modifiable = YES;
  106.             
  107.     return self;
  108. }
  109.  
  110.  
  111. - free
  112. {
  113.     epair_t    *e, *n;
  114.     
  115.     for (e=epairs ; e ; e=n)
  116.     {
  117.         n = e->next;
  118.         free (e);
  119.     }
  120.     return [super free];
  121. }
  122.  
  123. - (BOOL)modifiable
  124. {
  125.     return modifiable;
  126. }
  127.  
  128. - setModifiable: (BOOL)m
  129. {
  130.     modifiable = m;
  131.     return self;
  132. }
  133.  
  134. - removeObject: o
  135. {
  136.     o = [super removeObject: o];
  137.     if (numElements)
  138.         return o;
  139. // the entity is empty, so remove the entire thing
  140.     if ( self == [map_i objectAt: 0])
  141.         return o;    // never remove the world
  142.         
  143.     [map_i removeObject: self];
  144.     [self free];
  145.  
  146.     return o;
  147. }
  148.  
  149.  
  150. - (char *)valueForQKey: (char *)k
  151. {
  152.     epair_t    *e;
  153.     static char    ret[64];
  154.     
  155.     for (e=epairs ; e ; e=e->next)
  156.         if (!strcmp(k,e->key))
  157.         {
  158.             strcpy (ret, e->value);
  159.             return ret;
  160.         }
  161.     return "";
  162. }
  163.  
  164. - getVector: (vec3_t)v forKey: (char *)k
  165. {
  166.     char    *c;
  167.     
  168.     c = [self valueForQKey: k];
  169.  
  170.     v[0] = v[1] = v[2] = 0;
  171.         
  172.     sscanf (c, "%f %f %f", &v[0], &v[1], &v[2]);
  173.  
  174.     return self;
  175. }
  176.  
  177. - print
  178. {
  179.     epair_t    *e;
  180.     
  181.     for (e=epairs ; e ; e=e->next)
  182.         printf ("%20s : %20s\n",e->key, e->value);
  183.  
  184.     return self;
  185. }
  186.  
  187. - setKey:(char *)k toValue:(char *)v
  188. {
  189.     epair_t    *e;
  190.  
  191.     if (strlen(k) > MAX_KEY)
  192.         Error ("setKey: %s > MAX_KEY", k);
  193.     if (strlen(v) > MAX_VALUE)
  194.         Error ("setKey: %s > MAX_VALUE", v);
  195.         
  196.     while (*k && *k <= ' ')
  197.         k++;
  198.     if (!*k)
  199.         return self;    // don't set NULL values
  200.         
  201.     for (e=epairs ; e ; e=e->next)
  202.         if (!strcmp(k,e->key))
  203.         {
  204.             memset (e->value, 0, sizeof(e->value));
  205.             strcpy (e->value, v);
  206.             return self;
  207.         }
  208.  
  209.     e = malloc (sizeof(epair_t));
  210.     memset (e, 0, sizeof(epair_t));
  211.     
  212.     strcpy (e->key, k);
  213.     strcpy (e->value, v);
  214.     e->next = epairs;
  215.     epairs = e;
  216.     
  217.     return self;
  218. }
  219.  
  220. - (int)numPairs
  221. {
  222.     int    i;
  223.     epair_t    *e;
  224.     
  225.     i=0;
  226.     for (e=epairs ; e ; e=e->next)
  227.         i++;
  228.     return i;
  229. }
  230.  
  231. - (epair_t *)epairs
  232. {
  233.     return epairs;
  234. }
  235.  
  236. - removeKeyPair: (char *)key
  237. {
  238.     epair_t    *e, *e2;
  239.     
  240.     if (!epairs)
  241.         return self;
  242.     e = epairs;
  243.     if (!strcmp(e->key, key))
  244.     {
  245.         epairs = e->next;
  246.         free (e);
  247.         return self;
  248.     }
  249.     
  250.     for (; e ; e=e->next)
  251.     {
  252.         if (e->next && !strcmp(e->next->key, key))
  253.         {
  254.             e2 = e->next;
  255.             e->next = e2->next;
  256.             free (e2);
  257.             return self;
  258.         }
  259.     }
  260.     
  261.     printf ("WARNING: removeKeyPair: %s not found\n", key);
  262.     return self;    
  263. }
  264.  
  265.  
  266. /*
  267. =============
  268. targetname
  269.  
  270. If the entity does not have a "targetname" key, a unique one is generated
  271. =============
  272. */
  273. - (char *)targetname
  274. {
  275.     char    *t;
  276.     int        i, count;
  277.     id        ent;
  278.     int        tval, maxt;
  279.     char    name[20];
  280.     
  281.     t = [self valueForQKey: "targetname"];
  282.     if (t && t[0])
  283.         return t;
  284.         
  285. // make a unique name of the form t<number>
  286.     count = [map_i count];
  287.     maxt = 0;
  288.     for (i=1 ; i<count ; i++)
  289.     {
  290.         ent = [map_i objectAt: i];
  291.         t = [ent valueForQKey: "targetname"];
  292.         if (!t || t[0] != 't')
  293.             continue;
  294.         tval = atoi (t+1);
  295.         if (tval > maxt)
  296.             maxt = tval;
  297.     }
  298.     
  299.     sprintf (name,"t%i",maxt+1);
  300.     
  301.     [self setKey: "targetname" toValue: name];
  302.     
  303.     return [self valueForQKey: "targetname"];    // so it's not on the stack
  304. }
  305.  
  306. /*
  307. ==============================================================================
  308.  
  309. FILE METHODS
  310.  
  311. ==============================================================================
  312. */
  313.  
  314. int    nument;
  315.  
  316. - initFromTokens
  317. {
  318.     char    key[MAXTOKEN];
  319.     id        eclass, brush;
  320.     char    *spawn;
  321.     vec3_t    emins, emaxs;
  322.     vec3_t    org;
  323.     texturedef_t    td;
  324.     esize_t    esize;
  325.     int        i, c;
  326.     float    *color;
  327.     
  328.     [self init];
  329.  
  330.     if (!GetToken (true))
  331.     {
  332.         [self free];
  333.         return nil;
  334.     }
  335.  
  336.     if (strcmp (token, "{") )
  337.         Error ("initFromFileP: { not found");
  338.         
  339.     do
  340.     {
  341.         if (!GetToken (true))
  342.             break;
  343.         if (!strcmp (token, "}") )
  344.             break;
  345.         if (!strcmp (token, "{") )
  346.         {    // read a brush
  347.             brush = [[SetBrush alloc] initFromTokens: self];
  348.             [self addObject: brush];
  349.         }
  350.         else
  351.         {    // read a key / value pair
  352.             strcpy (key, token);
  353.             GetToken (false);
  354.             [self setKey: key toValue:token];
  355.         }
  356.     } while (1);
  357.     
  358.     nument++;
  359.  
  360. // get class
  361.     spawn = [self valueForQKey: "classname"];
  362.     eclass = [entity_classes_i classForName: spawn];
  363.  
  364.     esize = [eclass esize];
  365.  
  366.     [self getVector: org forKey: "origin"];
  367.     
  368.     if ([self count] && esize != esize_model)
  369.     {
  370.         printf ("WARNING:Entity with brushes and wrong model type\n"); 
  371.         [self empty];
  372.     }
  373.     
  374.     if (![self count] && esize == esize_model)
  375.     {
  376.         printf ("WARNING:Entity with no brushes and esize_model\n"); 
  377.         [texturepalette_i getTextureDef: &td];
  378.         for (i=0 ; i<3 ; i++)
  379.         {
  380.             emins[i] = org[i] - 8;
  381.             emaxs[i] = org[i] + 8;
  382.         }
  383.         brush = [[SetBrush alloc] initOwner: self mins:emins maxs:emaxs
  384.             texture: &td];
  385.         [self addObject: brush];
  386.     }
  387.     
  388. // create a brush if needed
  389.     if (esize == esize_fixed)
  390.         [self createFixedBrush: org];
  391.     else
  392.         modifiable = YES;
  393.  
  394. // set all the brush colors
  395.     color = [eclass drawColor];
  396.  
  397.     c = [self count];
  398.     for (i=0 ; i<c ; i++)
  399.     {
  400.         brush = [self objectAt: i];
  401.         [brush setEntityColor: color];
  402.     }
  403.     
  404.     return self;
  405. }
  406.  
  407.  
  408. - writeToFILE: (FILE *)f region:(BOOL)reg;
  409. {
  410.     epair_t    *e;
  411.     int        i;
  412.     id        new;
  413.     char    value[80];
  414.     vec3_t    mins, maxs, org;
  415.     float    *v;
  416.     BOOL    temporg;
  417.     char    oldang[80];
  418.     
  419.     temporg = NO;
  420.     if (reg)
  421.     {
  422.         if ( !strcmp ([self valueForQKey: "classname"], "info_player_start") )
  423.         {    // move the playerstart temporarily to the camera position
  424.             temporg = YES;
  425.             strcpy (oldang, [self valueForQKey: "angle"]);
  426.             sprintf (value, "%i", (int)([cameraview_i yawAngle]*180/M_PI));
  427.             [self setKey: "angle" toValue: value];
  428.         }
  429.         else if ( self != [map_i objectAt: 0] 
  430.         && [[self objectAt: 0] regioned] )
  431.             return self;    // skip the entire entity definition
  432.     }
  433.     
  434.     fprintf (f,"{\n");
  435.  
  436. // set an origin epair
  437.     if (!modifiable)
  438.     {
  439.         [[self objectAt: 0] getMins: mins maxs: maxs];
  440.         if (temporg)
  441.         {
  442.             [cameraview_i getOrigin: mins];
  443.             mins[0] -= 16;
  444.             mins[1] -= 16;
  445.             mins[2] -= 48;
  446.         }
  447.         new = [entity_classes_i classForName: 
  448.             [self valueForQKey: "classname"]];
  449.         if (new)
  450.             v = [new mins];
  451.         else
  452.             v = vec3_origin;
  453.             
  454.         VectorSubtract (mins, v, org);
  455.         sprintf (value, "%i %i %i",(int)org[0], (int)org[1], (int)org[2]);
  456.         [self setKey:"origin" toValue: value];
  457.     }
  458.         
  459.     for (e=epairs ; e ; e=e->next)
  460.         fprintf (f,"\"%s\"\t\"%s\"\n", e->key, e->value);
  461.         
  462. // fixed size entities don't save out brushes
  463.     if ( modifiable )
  464.     {
  465.         for (i=0 ; i<numElements ; i++)
  466.             [[self objectAt: i] writeToFILE: f region: reg];
  467.     }
  468.     
  469.     fprintf (f,"}\n");
  470.     
  471.     if (temporg)
  472.         [self setKey: "angle" toValue: oldang];
  473.  
  474.     return self;
  475. }
  476.  
  477. /*
  478. ==============================================================================
  479.  
  480. INTERACTION
  481.  
  482. ==============================================================================
  483. */
  484.  
  485. @end
  486.