doom3-gpl
Doom 3 GPL source release
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
EditorEntity.cpp
Go to the documentation of this file.
1 /*
2 ===========================================================================
3 
4 Doom 3 GPL Source Code
5 Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
6 
7 This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
8 
9 Doom 3 Source Code is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
13 
14 Doom 3 Source Code is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18 
19 You should have received a copy of the GNU General Public License
20 along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
21 
22 In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
23 
24 If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
25 
26 ===========================================================================
27 */
28 
29 #include "../../idlib/precompiled.h"
30 #pragma hdrstop
31 
32 #include "qe3.h"
33 #include "../../renderer/tr_local.h"
34 #include "../../renderer/model_local.h" // for idRenderModelMD5
35 int g_entityId = 1;
36 
37 #define CURVE_TAG "curve_"
38 
39 extern void Brush_Resize(brush_t *b, idVec3 vMin, idVec3 vMax);
40 
42 {
43 // int iCount = 0;
44 // for (epair_t* ep=ent->epairs ; ep ; ep=ep->next)
45 // {
46 // iCount++;
47 // }
48 
49  int iCount = ent->epairs.GetNumKeyVals();
50  return iCount;
51 }
52 
53 const char *GetKeyString(entity_t *ent, int iIndex)
54 {
55 // for (epair_t* ep=ent->epairs ; ep ; ep=ep->next)
56 // {
57 // if (!iIndex--)
58 // return ep->key;
59 // }
60 //
61 // assert(0);
62 // return NULL;
63 
64  if ( iIndex < GetNumKeys(ent) )
65  {
66  return ent->epairs.GetKeyVal(iIndex)->GetKey().c_str();
67  }
68 
69  assert(0);
70  return NULL;
71 }
72 
73 
74 /*
75  =======================================================================================================================
76  =======================================================================================================================
77  */
78 const char *ValueForKey(entity_t *ent, const char *key) {
79  return ent->epairs.GetString(key);
80 }
81 
82 /*
83  =======================================================================================================================
84  =======================================================================================================================
85  */
86 void TrackMD3Angles(entity_t *e, const char *key, const char *value) {
87  if ( idStr::Icmp(key, "angle") != 0 ) {
88  return;
89  }
90 
91  if ((e->eclass->fixedsize && e->eclass->nShowFlags & ECLASS_MISCMODEL) || EntityHasModel(e)) {
92  float a = FloatForKey(e, "angle");
93  float b = atof(value);
94  if (a != b) {
95  idVec3 vAngle;
96  vAngle[0] = vAngle[1] = 0;
97  vAngle[2] = -a;
98  Brush_Rotate(e->brushes.onext, vAngle, e->origin, true);
99  vAngle[2] = b;
100  Brush_Rotate(e->brushes.onext, vAngle, e->origin, true);
101  }
102  }
103 }
104 
105 /*
106  =======================================================================================================================
107  =======================================================================================================================
108  */
109 void SetKeyValue(entity_t *ent, const char *key, const char *value, bool trackAngles) {
110  if (ent == NULL) {
111  return;
112  }
113 
114  if (!key || !key[0]) {
115  return;
116  }
117 
118  if (trackAngles) {
119  TrackMD3Angles(ent, key, value);
120  }
121 
122  ent->epairs.Set(key, value);
123  GetVectorForKey(ent, "origin", ent->origin);
124 
125  // update sound in case this key was relevent
127 }
128 
129 /*
130  =======================================================================================================================
131  =======================================================================================================================
132  */
133 void SetKeyVec3(entity_t *ent, const char *key, idVec3 v) {
134  if (ent == NULL) {
135  return;
136  }
137 
138  if (!key || !key[0]) {
139  return;
140  }
141 
142  idStr str;
143  sprintf(str, "%g %g %g", v.x, v.y, v.z);
144  ent->epairs.Set(key, str);
145  GetVectorForKey(ent, "origin", ent->origin);
146 }
147 
148 /*
149  =======================================================================================================================
150  =======================================================================================================================
151  */
152 void SetKeyMat3(entity_t *ent, const char *key, idMat3 m) {
153  if (ent == NULL) {
154  return;
155  }
156 
157  if (!key || !key[0]) {
158  return;
159  }
160 
161  idStr str;
162 
163  sprintf(str, "%g %g %g %g %g %g %g %g %g",m[0][0],m[0][1],m[0][2],m[1][0],m[1][1],m[1][2],m[2][0],m[2][1],m[2][2]);
164 
165  ent->epairs.Set(key, str);
166  GetVectorForKey(ent, "origin", ent->origin);
167 }
168 
169 
170 
171 /*
172  =======================================================================================================================
173  =======================================================================================================================
174  */
175 void DeleteKey(entity_t *ent, const char *key) {
176  ent->epairs.Delete(key);
177  if (stricmp(key, "rotation") == 0) {
178  ent->rotation.Identity();
179  }
180 }
181 
182 /*
183  =======================================================================================================================
184  =======================================================================================================================
185  */
186 float FloatForKey(entity_t *ent, const char *key) {
187  const char *k;
188 
189  k = ValueForKey(ent, key);
190  if (k && *k) {
191  return atof(k);
192  }
193 
194  return 0.0;
195 }
196 
197 /*
198  =======================================================================================================================
199  =======================================================================================================================
200  */
201 int IntForKey(entity_t *ent, const char *key) {
202  const char *k;
203 
204  k = ValueForKey(ent, key);
205  return atoi(k);
206 }
207 
208 /*
209  =======================================================================================================================
210  =======================================================================================================================
211  */
212 bool GetVectorForKey(entity_t *ent, const char *key, idVec3 &vec) {
213  const char *k;
214  k = ValueForKey(ent, key);
215  if (k && strlen(k) > 0) {
216  sscanf(k, "%f %f %f", &vec[0], &vec[1], &vec[2]);
217  return true;
218  }
219  else {
220  vec[0] = vec[1] = vec[2] = 0;
221  }
222 
223  return false;
224 }
225 
226 /*
227  =======================================================================================================================
228  =======================================================================================================================
229  */
230 bool GetVector4ForKey(entity_t *ent, const char *key, idVec4 &vec) {
231  const char *k;
232  k = ValueForKey(ent, key);
233  if (k && strlen(k) > 0) {
234  sscanf(k, "%f %f %f %f", &vec[0], &vec[1], &vec[2], &vec[3]);
235  return true;
236  }
237  else {
238  vec[0] = vec[1] = vec[2] = vec[3] = 0;
239  }
240 
241  return false;
242 }
243 
244 /*
245  =======================================================================================================================
246  =======================================================================================================================
247  */
248 bool GetFloatForKey(entity_t *ent, const char *key, float *f) {
249  const char *k;
250  k = ValueForKey(ent, key);
251  if (k && strlen(k) > 0) {
252  *f = atof(k);
253  return true;
254  }
255 
256  *f = 0;
257  return false;
258 }
259 
260 /*
261  =======================================================================================================================
262  =======================================================================================================================
263  */
264 bool GetMatrixForKey(entity_t *ent, const char *key, idMat3 &mat) {
265  const char *k;
266  k = ValueForKey(ent, key);
267  if (k && strlen(k) > 0) {
268  sscanf
269  (
270  k,
271  "%f %f %f %f %f %f %f %f %f ",
272  &mat[0][0],
273  &mat[0][1],
274  &mat[0][2],
275  &mat[1][0],
276  &mat[1][1],
277  &mat[1][2],
278  &mat[2][0],
279  &mat[2][1],
280  &mat[2][2]
281  );
282  return true;
283  }
284  else {
285  mat.Identity();
286  }
287 
288  return false;
289 }
290 
291 /*
292  =======================================================================================================================
293  Entity_FreeEpairs Frees the entity epairs.
294  =======================================================================================================================
295  */
297  e->epairs.Clear();
298 }
299 
300 /*
301  =======================================================================================================================
302  Entity_AddToList
303  =======================================================================================================================
304  */
306  if (e->next || e->prev) {
307  Error("Entity_AddToList: allready linked");
308  }
309 
310  e->next = list->next;
311  list->next->prev = e;
312  list->next = e;
313  e->prev = list;
314 }
315 
316 /*
317  =======================================================================================================================
318  Entity_RemoveFromList
319  =======================================================================================================================
320  */
322  if ( !e->next || !e->prev ) {
323  Error("Entity_RemoveFromList: not linked");
324  }
325 
326  e->next->prev = e->prev;
327  e->prev->next = e->next;
328  e->next = e->prev = NULL;
329 }
330 
331 /*
332  =======================================================================================================================
333  Entity_Free Frees the entity and any brushes is has. The entity is removed from the global entities list.
334  =======================================================================================================================
335  */
336 void Entity_Free( entity_t *e ) {
337 
338  while ( e->brushes.onext != &e->brushes ) {
339  Brush_Free(e->brushes.onext);
340  }
341 
342  if ( e->next ) {
343  e->next->prev = e->prev;
344  e->prev->next = e->next;
345  }
346 
347  Entity_FreeEpairs( e );
348 
349  delete e;
350 }
351 
352 /*
353  =======================================================================================================================
354  Entity_MemorySize
355  =======================================================================================================================
356  */
357 
359 {
360  brush_t *b;
361  int size;
362 
363  size = sizeof( entity_t ) + e->epairs.Size();
364  for( b = e->brushes.onext; b != &e->brushes; b = b->onext )
365  {
366  size += Brush_MemorySize( b );
367 }
368  return( size );
369 }
370 
371 /*
372  =======================================================================================================================
373  ParseEpair
374  =======================================================================================================================
375  */
376 
377 struct EpairFixup {
378  const char *name;
379  int type;
380 };
381 
382 
384  { "origin", 1 },
385  { "rotation", 2 },
386  { "_color", 1 },
387  { "falloff", 0 },
388  { "light", 0 },
389  { "light_target", 1 },
390  { "light_up", 1 },
391  { "light_right", 1 },
392  { "light_start", 1 },
393  { "light_center", 1 },
394  { "light_end", 1 },
395  { "light_radius", 1 },
396  { "light_origin", 1 }
397 };
398 
399 const int FixupCount = sizeof(FloatFixups) / sizeof(EpairFixup);
400 
401 void FixFloats(idDict *dict) {
402  int count = dict->GetNumKeyVals();
403  for (int i = 0; i < count; i++) {
404  const idKeyValue *kv = dict->GetKeyVal(i);
405  for (int j = 0; j < FixupCount; j++) {
406  if (kv->GetKey().Icmp(FloatFixups[j].name) == 0) {
407  idStr val;
408  if (FloatFixups[j].type == 1) {
409  idVec3 v;
410  sscanf(kv->GetValue().c_str(), "%f %f %f", &v.x, &v.y, &v.z);
411  sprintf(val, "%g %g %g", v.x, v.y, v.z);
412  } else if (FloatFixups[j].type == 2) {
413  idMat3 mat;
414  sscanf(kv->GetValue().c_str(), "%f %f %f %f %f %f %f %f %f ",&mat[0][0],&mat[0][1],&mat[0][2],&mat[1][0],&mat[1][1],&mat[1][2],&mat[2][0],&mat[2][1],&mat[2][2]);
415  sprintf(val, "%g %g %g %g %g %g %g %g %g",mat[0][0],mat[0][1],mat[0][2],mat[1][0],mat[1][1],mat[1][2],mat[2][0],mat[2][1],mat[2][2]);
416  } else {
417  float f = atof(kv->GetValue().c_str());
418  sprintf(val, "%g", f);
419  }
420  dict->Set(kv->GetKey(), val);
421  break;
422  }
423  }
424  }
425 }
426 
427 void ParseEpair(idDict *dict) {
428  idStr key = token;
429  GetToken(false);
430  idStr val = token;
431 
432  if (key.Length() > 0) {
433  dict->Set(key, val);
434  }
435 }
436 
437 /*
438  =======================================================================================================================
439  =======================================================================================================================
440  */
442  if (ent) {
443  const char *model = ValueForKey(ent, "model");
444  const char *name = ValueForKey(ent, "name");
445  if (model && *model) {
446  if ( idStr::Icmp(model, name) ) {
447  return true;
448  }
449  }
450  }
451 
452  return false;
453 }
454 
455 /*
456  =======================================================================================================================
457  =======================================================================================================================
458  */
460  entity_t *ent = new entity_t;
461 
462  ent->prev = ent->next = NULL;
463  ent->brushes.prev = ent->brushes.next = NULL;
464  ent->brushes.oprev = ent->brushes.onext = NULL;
465  ent->brushes.owner = NULL;
466  ent->undoId = 0;
467  ent->redoId = 0;
468  ent->entityId = g_entityId++;
469  ent->origin.Zero();
470  ent->eclass = NULL;
471  ent->md3Class = NULL;
472  ent->lightOrigin.Zero();
473  ent->lightRotation.Identity();
474  ent->trackLightOrigin = false;
475  ent->rotation.Identity();
476  ent->lightDef = -1;
477  ent->modelDef = -1;
478  ent->soundEmitter = NULL;
479  ent->curve = NULL;
480  return ent;
481 }
482 
484 
485  if ( ent == NULL || ent->curve == NULL ) {
486  return;
487  }
488 
489  const idKeyValue *kv = ent->epairs.MatchPrefix( CURVE_TAG );
490  if ( kv == NULL ) {
491  if ( ent->curve ) {
492  delete ent->curve;
493  ent->curve = NULL;
494  if ( g_qeglobals.d_select_mode == sel_editpoint ) {
495  g_qeglobals.d_select_mode = sel_brush;
496  }
497  }
498  return;
499  }
500 
501  int c = ent->curve->GetNumValues();
502  idStr str = va( "%i ( ", c );
503  idVec3 v;
504  for ( int i = 0; i < c; i++ ) {
505  v = ent->curve->GetValue( i );
506  str += " ";
507  str += v.ToString();
508  str += " ";
509  }
510  str += " )";
511 
512  ent->epairs.Set( kv->GetKey(), str );
513 
514 }
515 
517  const idKeyValue *kv = ent->epairs.MatchPrefix( CURVE_TAG );
518  if ( kv ) {
519  idStr str = kv->GetKey().Right( kv->GetKey().Length() - strlen( CURVE_TAG ) );
520  if ( str.Icmp( "CatmullRomSpline" ) == 0 ) {
522  } else if ( str.Icmp( "Nurbs" ) == 0 ) {
523  return new idCurve_NURBS<idVec3>();
524  }
525  }
526  return NULL;
527 }
528 
530 
531  ent->curve = Entity_MakeCurve( ent );
532  const idKeyValue *kv = ent->epairs.MatchPrefix( CURVE_TAG );
533  if ( kv && ent->curve ) {
534  idLexer lex;
535  lex.LoadMemory( kv->GetValue(), kv->GetValue().Length(), "_curve" );
536  int numPoints = lex.ParseInt();
537  if ( numPoints > 0 ) {
538  float *fp = new float[numPoints * 3];
539  lex.Parse1DMatrix( numPoints * 3, fp );
540  int time = 0;
541  for ( int i = 0; i < numPoints * 3; i += 3 ) {
542  idVec3 v;
543  v.x = fp[i];
544  v.y = fp[i+1];
545  v.z = fp[i+2];
546  ent->curve->AddValue( time, v );
547  time += 100;
548  }
549  delete []fp;
550  }
551  }
552 
553 }
554 
555 entity_t *Entity_PostParse(entity_t *ent, brush_t *pList) {
556  bool has_brushes;
557  eclass_t *e;
558  brush_t *b;
559  idVec3 mins, maxs, zero;
560  idBounds bo;
561 
562  zero.Zero();
563 
564  Entity_SetCurveData( ent );
565 
566  if (ent->brushes.onext == &ent->brushes) {
567  has_brushes = false;
568  }
569  else {
570  has_brushes = true;
571  }
572 
573  bool needsOrigin = !GetVectorForKey(ent, "origin", ent->origin);
574  const char *pModel = ValueForKey(ent, "model");
575 
576  const char *cp = ValueForKey(ent, "classname");
577 
578  if (strlen(cp)) {
579  e = Eclass_ForName(cp, has_brushes);
580  } else {
581  const char *cp2 = ValueForKey(ent, "name");
582  if (strlen(cp2)) {
583  char buff[1024];
584  strcpy(buff, cp2);
585  int len = strlen(buff);
586  while ((isdigit(buff[len-1]) || buff[len-1] == '_') && len > 0) {
587  buff[len-1] = '\0';
588  len--;
589  }
590  e = Eclass_ForName(buff, has_brushes);
591  SetKeyValue(ent, "classname", buff, false);
592  } else {
593  e = Eclass_ForName("", has_brushes);
594  }
595  }
596 
597  idStr str;
598 
599  if (e->defArgs.GetString("model", "", str) && e->entityModel == NULL) {
600  e->entityModel = gameEdit->ANIM_GetModelFromEntityDef( &e->defArgs );
601  }
602 
603  ent->eclass = e;
604 
605  bool hasModel = EntityHasModel(ent);
606 
607  if (hasModel) {
608  ent->eclass->defArgs.GetString("model", "", str);
609  if (str.Length()) {
610  hasModel = false;
611  ent->epairs.Delete("model");
612  }
613  }
614 
615  if (e->nShowFlags & ECLASS_WORLDSPAWN) {
616  ent->origin.Zero();
617  needsOrigin = false;
618  ent->epairs.Delete( "model" );
619  } else if (e->nShowFlags & ECLASS_LIGHT) {
620  if (GetVectorForKey(ent, "light_origin", ent->lightOrigin)) {
621  GetMatrixForKey(ent, "light_rotation", ent->lightRotation);
622  ent->trackLightOrigin = true;
623  } else if (hasModel) {
624  SetKeyValue(ent, "light_origin", ValueForKey(ent, "origin"));
625  ent->lightOrigin = ent->origin;
626  if (GetMatrixForKey(ent, "rotation", ent->lightRotation)) {
627  SetKeyValue(ent, "light_rotation", ValueForKey(ent, "rotation"));
628  }
629  ent->trackLightOrigin = true;
630  }
631  } else if ( e->nShowFlags & ECLASS_ENV ) {
632  // need to create an origin from the bones here
633  idVec3 org;
634  idAngles ang;
635  bo.Clear();
636  bool hasBody = false;
637  const idKeyValue *arg = ent->epairs.MatchPrefix( "body ", NULL );
638  while ( arg ) {
639  sscanf( arg->GetValue(), "%f %f %f %f %f %f", &org.x, &org.y, &org.z, &ang.pitch, &ang.yaw, &ang.roll );
640  bo.AddPoint( org );
641  arg = ent->epairs.MatchPrefix( "body ", arg );
642  hasBody = true;
643  }
644  if (hasBody) {
645  ent->origin = bo.GetCenter();
646  }
647  }
648 
649  if (e->fixedsize || hasModel) { // fixed size entity
650  if (ent->brushes.onext != &ent->brushes) {
651  for (b = ent->brushes.onext; b != &ent->brushes; b = b->onext) {
652  b->entityModel = true;
653  }
654  }
655 
656  if (hasModel) {
657  // model entity
658  idRenderModel *modelHandle = renderModelManager->FindModel( pModel );
659 
660  if ( dynamic_cast<idRenderModelPrt*>( modelHandle ) || dynamic_cast<idRenderModelLiquid*>( modelHandle ) ) {
661  bo.Zero();
662  bo.ExpandSelf( 12.0f );
663  } else {
664  bo = modelHandle->Bounds( NULL );
665  }
666 
667  VectorCopy(bo[0], mins);
668  VectorCopy(bo[1], maxs);
669  for (int i = 0; i < 3; i++) {
670  if (mins[i] == maxs[i]) {
671  mins[i]--;
672  maxs[i]++;
673  }
674  }
675  VectorAdd(mins, ent->origin, mins);
676  VectorAdd(maxs, ent->origin, maxs);
677  b = Brush_Create(mins, maxs, &e->texdef);
678  b->modelHandle = modelHandle;
679 
680  float yaw = 0;
681  bool convertAngles = GetFloatForKey(ent, "angle", &yaw);
682  extern void Brush_Rotate(brush_t *b, idMat3 matrix, idVec3 origin, bool bBuild);
683  extern void Brush_Rotate(brush_t *b, idVec3 rot, idVec3 origin, bool bBuild);
684 
685  if (convertAngles) {
686  idVec3 rot(0, 0, yaw);
687  Brush_Rotate(b, rot, ent->origin, false);
688  }
689 
690  if (GetMatrixForKey(ent, "rotation", ent->rotation)) {
691  idBounds bo2;
692  bo2.FromTransformedBounds(bo, ent->origin, ent->rotation);
693  b->owner = ent;
694  Brush_Resize(b, bo2[0], bo2[1]);
695  }
696  Entity_LinkBrush(ent, b);
697  }
698 
699  if (!hasModel || (ent->eclass->nShowFlags & ECLASS_LIGHT && hasModel)) {
700  // create a custom brush
701  if (ent->trackLightOrigin) {
702  mins = e->mins + ent->lightOrigin;
703  maxs = e->maxs + ent->lightOrigin;
704  } else {
705  mins = e->mins + ent->origin;
706  maxs = e->maxs + ent->origin;
707  }
708 
709  b = Brush_Create(mins, maxs, &e->texdef);
710  GetMatrixForKey(ent, "rotation", ent->rotation);
711  Entity_LinkBrush(ent, b);
712  b->trackLightOrigin = ent->trackLightOrigin;
713  if ( e->texdef.name == NULL ) {
714  brushprimit_texdef_t bp;
715  texdef_t td;
716  td.SetName( ent->eclass->defMaterial );
717  Brush_SetTexture( b, &td, &bp, false );
718  }
719  }
720  } else { // brush entity
721  if (ent->brushes.next == &ent->brushes) {
722  printf("Warning: Brush entity with no brushes\n");
723  }
724 
725  if (!needsOrigin) {
726  idStr cn = ValueForKey(ent, "classname");
727  idStr name = ValueForKey(ent, "name");
728  idStr model = ValueForKey(ent, "model");
729  if (cn.Icmp("func_static") == 0) {
730  if (name.Icmp(model) == 0) {
731  needsOrigin = true;
732  }
733  }
734  }
735 
736  if (needsOrigin) {
737  idVec3 mins, maxs, mid;
738  int i;
739  char text[32];
740  mins[0] = mins[1] = mins[2] = 999999;
741  maxs[0] = maxs[1] = maxs[2] = -999999;
742 
743  // add in the origin
744  for (b = ent->brushes.onext; b != &ent->brushes; b = b->onext) {
745  Brush_Build(b, true, false, false);
746  for (i = 0; i < 3; i++) {
747  if (b->mins[i] < mins[i]) {
748  mins[i] = b->mins[i];
749  }
750 
751  if (b->maxs[i] > maxs[i]) {
752  maxs[i] = b->maxs[i];
753  }
754  }
755  }
756 
757  for (i = 0; i < 3; i++) {
758  ent->origin[i] = (mins[i] + ((maxs[i] - mins[i]) / 2));
759  }
760 
761  sprintf(text, "%i %i %i", (int)ent->origin[0], (int)ent->origin[1], (int)ent->origin[2]);
762  SetKeyValue(ent, "origin", text);
763  }
764 
765  if (!(e->nShowFlags & ECLASS_WORLDSPAWN)) {
766  if (e->defArgs.FindKey("model") == NULL && (pModel == NULL || (pModel && strlen(pModel) == 0))) {
767  SetKeyValue(ent, "model", ValueForKey(ent, "name"));
768  }
769  }
770  else {
771  DeleteKey(ent, "origin");
772  }
773  }
774 
775  // add all the brushes to the main list
776  if (pList) {
777  for (b = ent->brushes.onext; b != &ent->brushes; b = b->onext) {
778  b->next = pList->next;
779  pList->next->prev = b;
780  b->prev = pList;
781  pList->next = b;
782  }
783  }
784 
785  FixFloats(&ent->epairs);
786 
787  return ent;
788 
789 }
790 
791 /*
792  =======================================================================================================================
793  Entity_Parse If onlypairs is set, the classname info will not be looked up, and the entity will not be added to the
794  global list. Used for parsing the project.
795  =======================================================================================================================
796  */
797 entity_t *Entity_Parse(bool onlypairs, brush_t *pList) {
798  entity_t *ent;
799 
800  if (!GetToken(true)) {
801  return NULL;
802  }
803 
804  if (strcmp(token, "{")) {
805  Error("ParseEntity: { not found");
806  }
807 
808  ent = Entity_New();
809  ent->brushes.onext = ent->brushes.oprev = &ent->brushes;
810  ent->origin.Zero();
811 
812  int n = 0;
813  do {
814  if (!GetToken(true)) {
815  Warning("ParseEntity: EOF without closing brace");
816  return NULL;
817  }
818 
819  if (!strcmp(token, "}")) {
820  break;
821  }
822 
823  if (!strcmp(token, "{")) {
824  GetVectorForKey(ent, "origin", ent->origin);
825  brush_t *b = Brush_Parse(ent->origin);
826  if (b != NULL) {
827  b->owner = ent;
828 
829  // add to the end of the entity chain
830  b->onext = &ent->brushes;
831  b->oprev = ent->brushes.oprev;
832  ent->brushes.oprev->onext = b;
833  ent->brushes.oprev = b;
834  }
835  else {
836  break;
837  }
838  }
839  else {
840  ParseEpair(&ent->epairs);
841  }
842  } while (1);
843 
844  if (onlypairs) {
845  return ent;
846  }
847 
848  return Entity_PostParse(ent, pList);
849 }
850 
851 /*
852  =======================================================================================================================
853  =======================================================================================================================
854  */
856  for (int i = 0; i < 3; i++) {
857  out[i] = va[i] + ((vb[i] - va[i]) / 2);
858  }
859 }
860 
861 /*
862  =======================================================================================================================
863  Entity_Write
864  =======================================================================================================================
865  */
866 void Entity_Write(entity_t *e, FILE *f, bool use_region) {
867  brush_t *b;
868  idVec3 origin;
869  char text[128];
870  int count;
871 
872  // if none of the entities brushes are in the region, don't write the entity at all
873  if (use_region) {
874  // in region mode, save the camera position as playerstart
875  if (!strcmp(ValueForKey(e, "classname"), "info_player_start")) {
876  fprintf(f, "{\n");
877  fprintf(f, "\"classname\" \"info_player_start\"\n");
878  fprintf
879  (
880  f,
881  "\"origin\" \"%i %i %i\"\n",
882  (int)g_pParentWnd->GetCamera()->Camera().origin[0],
885  );
886  fprintf(f, "\"angle\" \"%i\"\n", (int)g_pParentWnd->GetCamera()->Camera().angles[YAW]);
887  fprintf(f, "}\n");
888  return;
889  }
890 
891  for (b = e->brushes.onext; b != &e->brushes; b = b->onext) {
892  if (!Map_IsBrushFiltered(b)) {
893  break; // got one
894  }
895  }
896 
897  if (b == &e->brushes) {
898  return; // nothing visible
899  }
900  }
901 
902  if (e->eclass->nShowFlags & ECLASS_PLUGINENTITY) {
903  // NOTE: the whole brush placement / origin stuff is a mess
904  VectorCopy(e->origin, origin);
905  sprintf(text, "%i %i %i", (int)origin[0], (int)origin[1], (int)origin[2]);
906  SetKeyValue(e, "origin", text);
907  }
908 
909  // if fixedsize, calculate a new origin based on the current brush position
910  else if (e->eclass->fixedsize || EntityHasModel(e)) {
911  if (!GetVectorForKey(e, "origin", origin)) {
912  VectorSubtract(e->brushes.onext->mins, e->eclass->mins, origin);
913  sprintf(text, "%i %i %i", (int)origin[0], (int)origin[1], (int)origin[2]);
914  SetKeyValue(e, "origin", text);
915  }
916  }
917 
918  fprintf(f, "{\n");
919 
920  count = e->epairs.GetNumKeyVals();
921  for (int j = 0; j < count; j++) {
922  fprintf(f, "\"%s\" \"%s\"\n", e->epairs.GetKeyVal(j)->GetKey().c_str(), e->epairs.GetKeyVal(j)->GetValue().c_str());
923  }
924 
925  if (!EntityHasModel(e)) {
926  count = 0;
927  for (b = e->brushes.onext; b != &e->brushes; b = b->onext) {
928  if (e->eclass->fixedsize && !b->entityModel) {
929  continue;
930  }
931  if (!use_region || !Map_IsBrushFiltered(b)) {
932  fprintf(f, "// brush %i\n", count);
933  count++;
934  Brush_Write( b, f, e->origin, ( g_PrefsDlg.m_bNewMapFormat != FALSE ) );
935  }
936  }
937  }
938 
939  fprintf(f, "}\n");
940 }
941 
942 /*
943  =======================================================================================================================
944  =======================================================================================================================
945  */
946 bool IsBrushSelected(brush_t *bSel) {
947  for (brush_t * b = selected_brushes.next; b != NULL && b != &selected_brushes; b = b->next) {
948  if (b == bSel) {
949  return true;
950  }
951  }
952 
953  return false;
954 }
955 
956 //
957 // =======================================================================================================================
958 // Entity_WriteSelected
959 // =======================================================================================================================
960 //
961 void Entity_WriteSelected(entity_t *e, FILE *f) {
962  brush_t *b;
963  idVec3 origin;
964  char text[128];
965  int count;
966 
967  for (b = e->brushes.onext; b != &e->brushes; b = b->onext) {
968  if (IsBrushSelected(b)) {
969  break; // got one
970  }
971  }
972 
973  if (b == &e->brushes) {
974  return; // nothing selected
975  }
976 
977  // if fixedsize, calculate a new origin based on the current brush position
978  if (e->eclass->fixedsize || EntityHasModel(e)) {
979  if (!GetVectorForKey(e, "origin", origin)) {
980  VectorSubtract(e->brushes.onext->mins, e->eclass->mins, origin);
981  sprintf(text, "%i %i %i", (int)origin[0], (int)origin[1], (int)origin[2]);
982  SetKeyValue(e, "origin", text);
983  }
984  }
985 
986  fprintf(f, "{\n");
987 
988  count = e->epairs.GetNumKeyVals();
989  for (int j = 0; j < count; j++) {
990  fprintf(f, "\"%s\" \"%s\"\n", e->epairs.GetKeyVal(j)->GetKey().c_str(), e->epairs.GetKeyVal(j)->GetValue().c_str());
991  }
992 
993  if (!EntityHasModel(e)) {
994  count = 0;
995  for (b = e->brushes.onext; b != &e->brushes; b = b->onext) {
996  if (e->eclass->fixedsize && !b->entityModel) {
997  continue;
998  }
999  if (IsBrushSelected(b)) {
1000  fprintf(f, "// brush %i\n", count);
1001  count++;
1002  Brush_Write( b, f, e->origin, ( g_PrefsDlg.m_bNewMapFormat != FALSE ) );
1003  }
1004  }
1005  }
1006 
1007  fprintf(f, "}\n");
1008 }
1009 
1010 //
1011 // =======================================================================================================================
1012 // Entity_WriteSelected to a CMemFile
1013 // =======================================================================================================================
1014 //
1015 void Entity_WriteSelected(entity_t *e, CMemFile *pMemFile) {
1016  brush_t *b;
1017  idVec3 origin;
1018  char text[128];
1019  int count;
1020 
1021  for (b = e->brushes.onext; b != &e->brushes; b = b->onext) {
1022  if (IsBrushSelected(b)) {
1023  break; // got one
1024  }
1025  }
1026 
1027  if (b == &e->brushes) {
1028  return; // nothing selected
1029  }
1030 
1031  // if fixedsize, calculate a new origin based on the current brush position
1032  if (e->eclass->fixedsize || EntityHasModel(e)) {
1033  if (!GetVectorForKey(e, "origin", origin)) {
1034  VectorSubtract(e->brushes.onext->mins, e->eclass->mins, origin);
1035  sprintf(text, "%i %i %i", (int)origin[0], (int)origin[1], (int)origin[2]);
1036  SetKeyValue(e, "origin", text);
1037  }
1038  }
1039 
1040  MemFile_fprintf(pMemFile, "{\n");
1041 
1042  count = e->epairs.GetNumKeyVals();
1043  for (int j = 0; j < count; j++) {
1044  MemFile_fprintf(pMemFile, "\"%s\" \"%s\"\n", e->epairs.GetKeyVal(j)->GetKey().c_str(), e->epairs.GetKeyVal(j)->GetValue().c_str());
1045  }
1046 
1047  if (!EntityHasModel(e)) {
1048  count = 0;
1049  for (b = e->brushes.onext; b != &e->brushes; b = b->onext) {
1050  if (e->eclass->fixedsize && !b->entityModel) {
1051  continue;
1052  }
1053  if (IsBrushSelected(b)) {
1054  MemFile_fprintf(pMemFile, "// brush %i\n", count);
1055  count++;
1056  Brush_Write( b, pMemFile, e->origin, ( g_PrefsDlg.m_bNewMapFormat != FALSE ) );
1057  }
1058  }
1059  }
1060 
1061  MemFile_fprintf(pMemFile, "}\n");
1062 }
1063 
1064 /*
1065  =======================================================================================================================
1066  =======================================================================================================================
1067  */
1068 void Entity_SetName(entity_t *e, const char *name) {
1069  CString oldName = ValueForKey(e, "name");
1070  CString oldModel = ValueForKey(e, "model");
1071  SetKeyValue(e, "name", name);
1072  if (oldName == oldModel) {
1073  SetKeyValue(e, "model", name);
1074  }
1075 }
1076 
1077 extern bool Entity_NameIsUnique(const char *name);
1078 
1079 /*
1080  =======================================================================================================================
1081  =======================================================================================================================
1082  */
1083 void Entity_Name(entity_t *e, bool force) {
1084  const char *name = ValueForKey(e, "name");
1085 
1086  if (!force && name && name[0]) {
1087  return;
1088  }
1089 
1090  if (name && name[0] && Entity_NameIsUnique(name)) {
1091  return;
1092  }
1093 
1094  bool setModel = false;
1095  if (name[0]) {
1096  const char *model = ValueForKey(e, "model");
1097  if (model[0]) {
1098  if ( idStr::Icmp(model, name) == 0 ) {
1099  setModel = true;
1100  }
1101  }
1102  }
1103 
1104  const char *eclass = ValueForKey(e, "classname");
1105  if (eclass && eclass[0]) {
1106  idStr str = cvarSystem->GetCVarString( "radiant_nameprefix" );
1107  int id = Map_GetUniqueEntityID(str, eclass);
1108  if (str.Length()) {
1109  SetKeyValue(e, "name", va("%s_%s_%i", str.c_str(), eclass, id));
1110  } else {
1111  SetKeyValue(e, "name", va("%s_%i", eclass, id));
1112  }
1113  if (setModel) {
1114  if (str.Length()) {
1115  SetKeyValue(e, "model", va("%s_%s_%i", str.c_str(), eclass, id));
1116  } else {
1117  SetKeyValue(e, "model", va("%s_%i", eclass, id));
1118  }
1119  }
1120  }
1121 }
1122 
1123 /*
1124  =======================================================================================================================
1125  Entity_Create Creates a new entity out of the selected_brushes list. If the entity class is fixed size, the brushes
1126  are only used to find a midpoint. Otherwise, the brushes have their ownership transfered to the new entity.
1127  =======================================================================================================================
1128  */
1129 entity_t *Entity_Create(eclass_t *c, bool forceFixed) {
1130  entity_t *e;
1131  brush_t *b;
1132  idVec3 mins, maxs, origin;
1133  char text[32];
1134  texdef_t td;
1135  brushprimit_texdef_t bp;
1136 
1137  // check to make sure the brushes are ok
1138  for (b = selected_brushes.next; b != &selected_brushes; b = b->next) {
1139  if (b->owner != world_entity) {
1140  Sys_Status("Entity NOT created, brushes not all from world\n");
1141  Sys_Beep();
1142  return NULL;
1143  }
1144  }
1145 
1146  idStr str;
1147  if (c->defArgs.GetString("model", "", str) && c->entityModel == NULL) {
1148  c->entityModel = gameEdit->ANIM_GetModelFromEntityDef( &c->defArgs );
1149  }
1150 
1151  // create it
1152  e = Entity_New();
1153  e->brushes.onext = e->brushes.oprev = &e->brushes;
1154  e->eclass = c;
1155  e->epairs.Copy(c->args);
1156  SetKeyValue(e, "classname", c->name);
1157  Entity_Name(e, false);
1158 
1159  // add the entity to the entity list
1161 
1162  if (c->fixedsize) {
1163  //
1164  // just use the selection for positioning b = selected_brushes.next; for (i=0 ;
1165  // i<3 ; i++) { e->origin[i] = b->mins[i] - c->mins[i]; }
1166  //
1167  Select_GetMid(e->origin);
1168  VectorCopy(e->origin, origin);
1169 
1170  // create a custom brush
1171  VectorAdd(c->mins, e->origin, mins);
1172  VectorAdd(c->maxs, e->origin, maxs);
1173 
1174  b = Brush_Create(mins, maxs, &c->texdef);
1175 
1176  Entity_LinkBrush(e, b);
1177 
1178  if (c->defMaterial.Length()) {
1179  td.SetName(c->defMaterial);
1180  Brush_SetTexture(b, &td, &bp, false);
1181  }
1182 
1183 
1184  // delete the current selection
1185  Select_Delete();
1186 
1187  // select the new brush
1188  b->next = b->prev = &selected_brushes;
1189  selected_brushes.next = selected_brushes.prev = b;
1190 
1191  Brush_Build(b);
1192  }
1193  else {
1194 
1195  Select_GetMid(origin);
1196 
1197  // change the selected brushes over to the new entity
1198  for (b = selected_brushes.next; b != &selected_brushes; b = b->next) {
1199  Entity_UnlinkBrush(b);
1200  Entity_LinkBrush(e, b);
1201  Brush_Build(b); // so the key brush gets a name
1202  if (c->defMaterial.Length()) {
1203  td.SetName(c->defMaterial);
1204  Brush_SetTexture(b, &td, &bp, false);
1205  }
1206 
1207  }
1208 
1209  //for (int i = 0; i < 3; i++) {
1210  // origin[i] = vMin[i] + vMax[i] * 0.5;
1211  //}
1212 
1213  if (!forceFixed) {
1214  SetKeyValue(e, "model", ValueForKey(e, "name"));
1215  }
1216  }
1217 
1218  sprintf(text, "%i %i %i", (int)origin[0], (int)origin[1], (int)origin[2]);
1219  SetKeyValue(e, "origin", text);
1220  VectorCopy(origin, e->origin);
1221 
1222  Sys_UpdateWindows(W_ALL);
1223  return e;
1224 }
1225 
1226 void Brush_MakeDirty(brush_t *b) {
1227  for (face_t *f = b->brush_faces; f; f = f->next) {
1228  f->dirty = true;
1229  }
1230 }
1231 /*
1232  =======================================================================================================================
1233  Entity_LinkBrush
1234  =======================================================================================================================
1235  */
1236 void Entity_LinkBrush(entity_t *e, brush_t *b) {
1237  if (b->oprev || b->onext) {
1238  Error("Entity_LinkBrush: Allready linked");
1239  }
1240 
1241  Brush_MakeDirty(b);
1242 
1243  b->owner = e;
1244 
1245  b->onext = e->brushes.onext;
1246  b->oprev = &e->brushes;
1247  e->brushes.onext->oprev = b;
1248  e->brushes.onext = b;
1249 }
1250 
1251 /*
1252  =======================================================================================================================
1253  Entity_UnlinkBrush
1254  =======================================================================================================================
1255  */
1256 void Entity_UnlinkBrush(brush_t *b) {
1257  // if (!b->owner || !b->onext || !b->oprev)
1258  if (!b->onext || !b->oprev) {
1259  Error("Entity_UnlinkBrush: Not currently linked");
1260  }
1261 
1262  b->onext->oprev = b->oprev;
1263  b->oprev->onext = b->onext;
1264  b->onext = b->oprev = NULL;
1265  b->owner = NULL;
1266 }
1267 
1268 /*
1269  =======================================================================================================================
1270  Entity_Clone
1271  =======================================================================================================================
1272  */
1274  entity_t *n;
1275 
1276  n = Entity_New();
1277  n->brushes.onext = n->brushes.oprev = &n->brushes;
1278  n->eclass = e->eclass;
1279  n->rotation = e->rotation;
1280  n->origin = e->origin;
1281 
1282  // add the entity to the entity list
1284 
1285  n->epairs = e->epairs;
1286 
1287  return n;
1288 }
1289 
1290 /*
1291  =======================================================================================================================
1292  =======================================================================================================================
1293  */
1294 int GetUniqueTargetId(int iHint) {
1295  int iMin, iMax, i;
1296  BOOL fFound;
1297  entity_t *pe;
1298 
1299  fFound = FALSE;
1300  pe = entities.next;
1301  iMin = 0;
1302  iMax = 0;
1303 
1304  for (; pe != NULL && pe != &entities; pe = pe->next) {
1305  i = IntForKey(pe, "target");
1306  if (i) {
1307  iMin = Min(i, iMin);
1308  iMax = Max(i, iMax);
1309  if (i == iHint) {
1310  fFound = TRUE;
1311  }
1312  }
1313  }
1314 
1315  if (fFound) {
1316  return iMax + 1;
1317  }
1318  else {
1319  return iHint;
1320  }
1321 }
1322 
1323 /*
1324  =======================================================================================================================
1325  =======================================================================================================================
1326  */
1327 entity_t *FindEntity(const char *pszKey, const char *pszValue) {
1328  entity_t *pe;
1329 
1330  pe = entities.next;
1331 
1332  for (; pe != NULL && pe != &entities; pe = pe->next) {
1333  if (!strcmp(ValueForKey(pe, pszKey), pszValue)) {
1334  return pe;
1335  }
1336  }
1337 
1338  return NULL;
1339 }
1340 
1341 /*
1342  =======================================================================================================================
1343  =======================================================================================================================
1344  */
1345 entity_t *FindEntityInt(const char *pszKey, int iValue) {
1346  entity_t *pe;
1347 
1348  pe = entities.next;
1349 
1350  for (; pe != NULL && pe != &entities; pe = pe->next) {
1351  if (IntForKey(pe, pszKey) == iValue) {
1352  return pe;
1353  }
1354  }
1355 
1356  return NULL;
1357 }
1358 
1359 /*
1360 ====================
1361 Entity_UpdateSoundEmitter
1362 
1363 Deletes the soundEmitter if the entity should not emit a sound due
1364 to it not having one, being filtered away, or the sound mode being turned off.
1365 
1366 Creates or updates the soundEmitter if needed
1367 ====================
1368 */
1370  bool playing = false;
1371 
1372  // if an entity doesn't have any brushes at all, don't do anything
1373  // if the brush isn't displayed (filtered or culled), don't do anything
1374  if ( g_pParentWnd->GetCamera()->GetSoundMode()
1375  && ent->brushes.onext != &ent->brushes && !FilterBrush(ent->brushes.onext) ) {
1376  // check for sounds
1377  const char *v = ValueForKey( ent, "s_shader" );
1378  if ( v[0] ) {
1379  refSound_t sound;
1380 
1381  gameEdit->ParseSpawnArgsToRefSound( &ent->epairs, &sound );
1382  if ( !sound.waitfortrigger ) { // waitfortrigger will not start playing immediately
1383  if ( !ent->soundEmitter ) {
1384  ent->soundEmitter = g_qeglobals.sw->AllocSoundEmitter();
1385  }
1386  playing = true;
1387  ent->soundEmitter->UpdateEmitter( ent->origin, 0, &sound.parms );
1388  // always play on a single channel, so updates always override
1389  ent->soundEmitter->StartSound( sound.shader, SCHANNEL_ONE );
1390  }
1391  }
1392  }
1393 
1394  // delete the soundEmitter if not used
1395  if ( !playing && ent->soundEmitter ) {
1396  ent->soundEmitter->Free( true );
1397  ent->soundEmitter = NULL;
1398  }
1399 
1400 }
1401 
CMainFrame * g_pParentWnd
Definition: MainFrm.cpp:73
bool FilterBrush(brush_t *pb)
Definition: XYWnd.cpp:3167
const int FixupCount
int entityId
Definition: EditorEntity.h:36
#define strcmp
Definition: Str.h:41
#define stricmp
Definition: Str.h:64
bool GetMatrixForKey(entity_t *ent, const char *key, idMat3 &mat)
void WINAPI Sys_UpdateWindows(int nBits)
Definition: MainFrm.cpp:3974
GLsizei const GLfloat * value
Definition: glext.h:3614
int g_entityId
type GetValue(const int index) const
Definition: Curve.h:58
entity_t * world_entity
Definition: EditorMap.cpp:49
idVec3 lightOrigin
Definition: EditorEntity.h:45
bool waitfortrigger
Definition: Game.h:217
idCurve< idVec3 > * Entity_MakeCurve(entity_t *ent)
assert(prefInfo.fullscreenBtn)
idCVarSystem * cvarSystem
Definition: CVarSystem.cpp:487
void Delete(const char *key)
Definition: Dict.cpp:496
bool GetSoundMode()
Definition: CamWnd.h:119
idVec3 GetCenter(void) const
Definition: Bounds.h:211
void Zero(void)
Definition: Bounds.h:206
const EpairFixup FloatFixups[]
void Entity_FreeEpairs(entity_t *e)
brush_t selected_brushes
Definition: EditorMap.cpp:40
void Entity_Write(entity_t *e, FILE *f, bool use_region)
void Entity_Free(entity_t *e)
bool IsBrushSelected(brush_t *bSel)
const GLdouble * v
Definition: glext.h:2936
const idStr & GetKey(void) const
Definition: Dict.h:52
GLuint GLenum matrix
Definition: glext.h:5179
void Entity_UnlinkBrush(brush_t *b)
ID_INLINE T Max(T x, T y)
Definition: Lib.h:158
bool GetFloatForKey(entity_t *ent, const char *key, float *f)
#define VectorSubtract(a, b, c)
Definition: Vector.h:1995
int Length(void) const
Definition: Str.h:702
int Parse1DMatrix(int x, float *m)
Definition: Lexer.cpp:1300
GLenum GLsizei n
Definition: glext.h:3705
void Entity_SetCurveData(entity_t *ent)
float z
Definition: Vector.h:320
const idKeyValue * MatchPrefix(const char *prefix, const idKeyValue *lastMatch=NULL) const
Definition: Dict.cpp:523
bool trackLightOrigin
Definition: EditorEntity.h:47
case const int
Definition: Callbacks.cpp:52
#define VectorCopy(a, b)
Definition: Vector.h:1999
brush_t * Brush_Parse(idVec3 origin)
idVec3 origin
Definition: EditorEntity.h:37
void Sys_Status(const char *psz, int part)
Definition: Radiant.cpp:465
camera_t & Camera()
Definition: CamWnd.h:90
const char * ValueForKey(entity_t *ent, const char *key)
Definition: Vector.h:316
void Brush_Free(brush_t *b, bool bRemoveNode)
#define VectorAdd(a, b, c)
Definition: Vector.h:1996
idAngles angles
Definition: CamWnd.h:49
void Clear(void)
Definition: Bounds.h:201
GLuint GLuint GLsizei GLenum type
Definition: glext.h:2845
int undoId
Definition: EditorEntity.h:36
void MemFile_fprintf(CMemFile *pMemFile, const char *string,...)
Definition: EditorMap.cpp:1526
entity_t * Entity_PostParse(entity_t *ent, brush_t *pList)
GLenum GLsizei len
Definition: glext.h:3472
void Set(const char *key, const char *value)
Definition: Dict.cpp:275
void Identity(void)
Definition: Matrix.h:591
float x
Definition: Vector.h:318
virtual void Free(bool immediate)=0
idMat3 lightRotation
Definition: EditorEntity.h:46
size_t Size(void) const
Definition: Dict.h:91
int i
Definition: process.py:33
int GetNumKeys(entity_t *ent)
#define BOOL
Definition: mprintf.c:71
entity_t * Entity_Parse(bool onlypairs, brush_t *pList)
int ParseInt(void)
Definition: Lexer.cpp:1227
void Brush_SetTexture(brush_t *b, texdef_t *texdef, brushprimit_texdef_t *brushprimit_texdef, bool bFitScale)
brush_t brushes
Definition: EditorEntity.h:35
void Brush_Build(brush_t *b, bool bSnap, bool bMarkMap, bool bConvert, bool updateLights)
void Copy(const idDict &other)
Definition: Dict.cpp:70
int Icmp(const char *text) const
Definition: Str.h:667
void ParseEpair(idDict *dict)
idMat3 rotation
Definition: EditorEntity.h:44
void SetKeyValue(entity_t *ent, const char *key, const char *value, bool trackAngles)
idGameEdit * gameEdit
Definition: GameEdit.cpp:668
entity_t * Entity_New()
bool AddPoint(const idVec3 &v)
Definition: Bounds.h:226
void Error(const char *pFormat,...)
Definition: cmdlib.cpp:45
Definition: Lexer.h:137
void Entity_UpdateSoundEmitter(entity_t *ent)
GLuint GLuint GLsizei count
Definition: glext.h:2845
CCamWnd * GetCamera()
Definition: MainFrm.h:123
void Entity_UpdateCurveData(entity_t *ent)
qhandle_t lightDef
Definition: EditorEntity.h:38
const GLubyte * c
Definition: glext.h:4677
const char * GetString(const char *key, const char *defaultString="") const
Definition: Dict.h:240
bool EntityHasModel(entity_t *ent)
Definition: Vector.h:808
void VectorMidpoint(idVec3 va, idVec3 vb, idVec3 &out)
bool GetVector4ForKey(entity_t *ent, const char *key, idVec4 &vec)
eclass_t * md3Class
Definition: EditorEntity.h:43
Definition: Dict.h:65
struct entity_s * prev
Definition: EditorEntity.h:34
#define NULL
Definition: Lib.h:88
virtual const char * GetCVarString(const char *name) const =0
void Clear(void)
Definition: Dict.cpp:201
virtual idRenderModel * FindModel(const char *modelName)=0
float y
Definition: Vector.h:319
void Brush_Resize(brush_t *b, idVec3 vMin, idVec3 vMax)
void SetKeyMat3(entity_t *ent, const char *key, idMat3 m)
struct entity_s * next
Definition: EditorEntity.h:34
float roll
Definition: Angles.h:55
const idStr & GetValue(void) const
Definition: Dict.h:53
struct entity_s entity_t
const idSoundShader * shader
Definition: Game.h:214
const char * Right(int len, idStr &result) const
Definition: Str.h:896
int Map_GetUniqueEntityID(const char *prefix, const char *eclass)
Definition: EditorMap.cpp:163
idVec3 origin
Definition: CamWnd.h:48
void FromTransformedBounds(const idBounds &bounds, const idVec3 &origin, const idMat3 &axis)
Definition: Bounds.cpp:232
entity_t * Entity_Clone(entity_t *e)
float pitch
Definition: Angles.h:53
void TrackMD3Angles(entity_t *e, const char *key, const char *value)
GLubyte GLubyte GLubyte a
Definition: glext.h:4662
void DeleteKey(entity_t *ent, const char *key)
int Brush_MemorySize(brush_t *b)
int LoadMemory(const char *ptr, int length, const char *name, int startLine=1)
Definition: Lexer.cpp:1646
void Entity_SetName(entity_t *e, const char *name)
virtual int StartSound(const idSoundShader *shader, const s_channelType channel, float diversity=0, int shaderFlags=0, bool allowSlow=true)=0
virtual idBounds Bounds(const struct renderEntity_s *ent=NULL) const =0
int GetUniqueTargetId(int iHint)
qhandle_t modelDef
Definition: EditorEntity.h:39
const char * ToString(int precision=2) const
Definition: Vector.cpp:221
void Brush_Write(brush_t *b, FILE *f, const idVec3 &origin, bool newFormat)
#define YAW
Definition: Angles.h:42
idCurve< idVec3 > * curve
Definition: EditorEntity.h:48
void Entity_RemoveFromList(entity_t *e)
GLubyte GLubyte b
Definition: glext.h:4662
bool Entity_NameIsUnique(const char *name)
Definition: EditorMap.cpp:194
idSoundEmitter * soundEmitter
Definition: EditorEntity.h:40
bool GetVectorForKey(entity_t *ent, const char *key, idVec3 &vec)
void Entity_LinkBrush(entity_t *e, brush_t *b)
idRenderModelManager * renderModelManager
Definition: Matrix.h:333
int redoId
Definition: EditorEntity.h:36
float yaw
Definition: Angles.h:54
GLuint id
Definition: glext.h:3103
soundShaderParms_t parms
Definition: Game.h:218
tuple f
Definition: idal.py:89
void Brush_Rotate(brush_t *b, idMat3 matrix, idVec3 origin, bool bBuild)
const GLcharARB * name
Definition: glext.h:3629
entity_t * FindEntity(const char *pszKey, const char *pszValue)
GLsizeiptr size
Definition: glext.h:3112
virtual void UpdateEmitter(const idVec3 &origin, int listenerId, const soundShaderParms_t *parms)=0
CPrefsDlg & g_PrefsDlg
Definition: MainFrm.cpp:75
entity_t entities
Definition: EditorMap.cpp:47
Definition: Str.h:116
virtual int AddValue(const float time, const type &value)
Definition: Curve.h:116
BOOL m_bNewMapFormat
Definition: PrefsDlg.h:99
int IntForKey(entity_t *ent, const char *key)
brush_t * Brush_Create(idVec3 mins, idVec3 maxs, texdef_t *texdef)
idDict epairs
Definition: EditorEntity.h:42
const char * c_str(void) const
Definition: Str.h:487
#define FALSE
Definition: mprintf.c:70
const char * GetKeyString(entity_t *ent, int iIndex)
const idKeyValue * GetKeyVal(int index) const
Definition: Dict.h:294
entity_t * Entity_Create(eclass_t *c, bool forceFixed)
void Entity_AddToList(entity_t *e, entity_t *list)
#define TRUE
Definition: mprintf.c:69
GLint j
Definition: qgl.h:264
idBounds & ExpandSelf(const float d)
Definition: Bounds.h:322
virtual void ParseSpawnArgsToRefSound(const idDict *args, refSound_t *refSound)
Definition: Entity.cpp:324
char * va(const char *fmt,...)
Definition: Str.cpp:1568
int GetNumValues(void) const
Definition: Curve.h:56
virtual idRenderModel * ANIM_GetModelFromEntityDef(const char *classname)
void SetKeyVec3(entity_t *ent, const char *key, idVec3 v)
float FloatForKey(entity_t *ent, const char *key)
int Entity_MemorySize(entity_t *e)
void Entity_WriteSelected(entity_t *e, FILE *f)
int GetNumKeyVals(void) const
Definition: Dict.h:290
void Zero(void)
Definition: Vector.h:415
ID_INLINE T Min(T x, T y)
Definition: Lib.h:159
int sprintf(idStr &string, const char *fmt,...)
Definition: Str.cpp:1528
#define CURVE_TAG
void Brush_MakeDirty(brush_t *b)
entity_t * FindEntityInt(const char *pszKey, int iValue)
eclass_t * eclass
Definition: EditorEntity.h:41
void FixFloats(idDict *dict)
void Entity_Name(entity_t *e, bool force)
eclass_t * Eclass_ForName(const char *name, bool has_brushes)
const char * name
bool Map_IsBrushFiltered(brush_t *b)
Definition: EditorMap.cpp:924