Entity.m 8.0 KB

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