g_spawn.cpp 48 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656
  1. // leave this line at the top for all g_xxxx.cpp files...
  2. #include "g_headers.h"
  3. #include "Q3_Interface.h"
  4. #include "g_local.h"
  5. #include "g_functions.h"
  6. extern cvar_t *g_spskill;
  7. extern cvar_t *g_delayedShutdown;
  8. // these vars I moved here out of the level_locals_t struct simply because it's pointless to try saving them,
  9. // and the level_locals_t struct is included in the save process... -slc
  10. //
  11. qboolean spawning = qfalse; // the G_Spawn*() functions are valid (only turned on during one function)
  12. int numSpawnVars;
  13. char *spawnVars[MAX_SPAWN_VARS][2]; // key / value pairs
  14. int numSpawnVarChars;
  15. char spawnVarChars[MAX_SPAWN_VARS_CHARS];
  16. int delayedShutDown = 0;
  17. #include "../qcommon/sstring.h"
  18. //NOTENOTE: Be sure to change the mirrored code in cgmain.cpp
  19. typedef map< sstring_t, unsigned char, less<sstring_t>, allocator< unsigned char > > namePrecache_m;
  20. namePrecache_m *as_preCacheMap = NULL;
  21. char *G_AddSpawnVarToken( const char *string );
  22. void AddSpawnField(char *field, char *value)
  23. {
  24. int i;
  25. for(i=0;i<numSpawnVars;i++)
  26. {
  27. if (Q_stricmp(spawnVars[i][0], field) == 0)
  28. {
  29. spawnVars[ i ][1] = G_AddSpawnVarToken( value );
  30. return;
  31. }
  32. }
  33. spawnVars[ numSpawnVars ][0] = G_AddSpawnVarToken( field );
  34. spawnVars[ numSpawnVars ][1] = G_AddSpawnVarToken( value );
  35. numSpawnVars++;
  36. }
  37. qboolean G_SpawnField( unsigned int uiField, char **ppKey, char **ppValue )
  38. {
  39. if ( uiField >= numSpawnVars )
  40. return qfalse;
  41. (*ppKey) = spawnVars[uiField][0];
  42. *ppValue = spawnVars[uiField][1];
  43. return qtrue;
  44. }
  45. qboolean G_SpawnString( const char *key, const char *defaultString, char **out ) {
  46. int i;
  47. if ( !spawning ) {
  48. *out = (char *)defaultString;
  49. // G_Error( "G_SpawnString() called while not spawning" );
  50. }
  51. for ( i = 0 ; i < numSpawnVars ; i++ ) {
  52. if ( !Q_stricmp( key, spawnVars[i][0] ) ) {
  53. *out = spawnVars[i][1];
  54. return qtrue;
  55. }
  56. }
  57. *out = (char *)defaultString;
  58. return qfalse;
  59. }
  60. qboolean G_SpawnFloat( const char *key, const char *defaultString, float *out ) {
  61. char *s;
  62. qboolean present;
  63. present = G_SpawnString( key, defaultString, &s );
  64. *out = atof( s );
  65. return present;
  66. }
  67. qboolean G_SpawnInt( const char *key, const char *defaultString, int *out ) {
  68. char *s;
  69. qboolean present;
  70. present = G_SpawnString( key, defaultString, &s );
  71. *out = atoi( s );
  72. return present;
  73. }
  74. qboolean G_SpawnVector( const char *key, const char *defaultString, float *out ) {
  75. char *s;
  76. qboolean present;
  77. present = G_SpawnString( key, defaultString, &s );
  78. sscanf( s, "%f %f %f", &out[0], &out[1], &out[2] );
  79. return present;
  80. }
  81. qboolean G_SpawnVector4( const char *key, const char *defaultString, float *out ) {
  82. char *s;
  83. qboolean present;
  84. present = G_SpawnString( key, defaultString, &s );
  85. sscanf( s, "%f %f %f %f", &out[0], &out[1], &out[2], &out[3] );
  86. return present;
  87. }
  88. qboolean G_SpawnFlag( const char *key, int flag, int *out )
  89. {
  90. //find that key
  91. for ( int i = 0 ; i < numSpawnVars ; i++ )
  92. {
  93. if ( !strcmp( key, spawnVars[i][0] ) )
  94. {
  95. //found the key
  96. if ( atoi( spawnVars[i][1] ) != 0 )
  97. {//if it's non-zero, and in the flag
  98. *out |= flag;
  99. }
  100. else
  101. {//if it's zero, or out the flag
  102. *out &= ~flag;
  103. }
  104. return qtrue;
  105. }
  106. }
  107. return qfalse;
  108. }
  109. qboolean G_SpawnAngleHack( const char *key, const char *defaultString, float *out )
  110. {
  111. char *s;
  112. qboolean present;
  113. float temp = 0;
  114. present = G_SpawnString( key, defaultString, &s );
  115. sscanf( s, "%f", &temp );
  116. out[0] = 0;
  117. out[1] = temp;
  118. out[2] = 0;
  119. return present;
  120. }
  121. stringID_table_t flagTable [] =
  122. {
  123. //"noTED", EF_NO_TED,
  124. //stringID_table_t Must end with a null entry
  125. "", NULL
  126. };
  127. //
  128. // fields are needed for spawning from the entity string
  129. //
  130. typedef enum {
  131. F_INT,
  132. F_FLOAT,
  133. F_LSTRING, // string on disk, pointer in memory, TAG_LEVEL
  134. F_GSTRING, // string on disk, pointer in memory, TAG_GAME
  135. F_VECTOR,
  136. F_VECTOR4,
  137. F_ANGLEHACK,
  138. F_ENTITY, // index on disk, pointer in memory
  139. F_ITEM, // index on disk, pointer in memory
  140. F_CLIENT, // index on disk, pointer in memory
  141. F_PARM1, // Special case for parms
  142. F_PARM2, // Special case for parms
  143. F_PARM3, // Special case for parms
  144. F_PARM4, // Special case for parms
  145. F_PARM5, // Special case for parms
  146. F_PARM6, // Special case for parms
  147. F_PARM7, // Special case for parms
  148. F_PARM8, // Special case for parms
  149. F_PARM9, // Special case for parms
  150. F_PARM10, // Special case for parms
  151. F_PARM11, // Special case for parms
  152. F_PARM12, // Special case for parms
  153. F_PARM13, // Special case for parms
  154. F_PARM14, // Special case for parms
  155. F_PARM15, // Special case for parms
  156. F_PARM16, // Special case for parms
  157. F_FLAG, // special case for flags
  158. F_IGNORE
  159. } fieldtype_t;
  160. typedef struct
  161. {
  162. char *name;
  163. int ofs;
  164. fieldtype_t type;
  165. int flags;
  166. } field_t;
  167. field_t fields[] = {
  168. //Fields for benefit of Radiant only
  169. {"autobound", FOFS(classname), F_IGNORE},
  170. {"groupname", FOFS(classname), F_IGNORE},
  171. {"noBasicSounds", FOFS(classname), F_IGNORE},//will be looked at separately
  172. {"noCombatSounds", FOFS(classname), F_IGNORE},//will be looked at separately
  173. {"noExtraSounds", FOFS(classname), F_IGNORE},//will be looked at separately
  174. {"classname", FOFS(classname), F_LSTRING},
  175. {"origin", FOFS(s.origin), F_VECTOR},
  176. {"mins", FOFS(mins), F_VECTOR},
  177. {"maxs", FOFS(maxs), F_VECTOR},
  178. {"model", FOFS(model), F_LSTRING},
  179. {"model2", FOFS(model2), F_LSTRING},
  180. {"model3", FOFS(target), F_LSTRING},//for misc_replicator_item only!!!
  181. {"model4", FOFS(target2), F_LSTRING},//for misc_replicator_item only!!!
  182. {"model5", FOFS(target3), F_LSTRING},//for misc_replicator_item only!!!
  183. {"model6", FOFS(target4), F_LSTRING},//for misc_replicator_item only!!!
  184. {"spawnflags", FOFS(spawnflags), F_INT},
  185. {"speed", FOFS(speed), F_FLOAT},
  186. {"duration", FOFS(speed), F_FLOAT},//for psycho jism
  187. {"interest", FOFS(health), F_INT},//For target_interest
  188. {"target", FOFS(target), F_LSTRING},
  189. {"target2", FOFS(target2), F_LSTRING},
  190. {"target3", FOFS(target3), F_LSTRING},
  191. {"target4", FOFS(target4), F_LSTRING},
  192. {"targetJump", FOFS(targetJump), F_LSTRING},
  193. {"targetname", FOFS(targetname), F_LSTRING},
  194. {"material", FOFS(material), F_INT},
  195. {"message", FOFS(message), F_LSTRING},
  196. {"team", FOFS(team), F_LSTRING},
  197. {"mapname", FOFS(message), F_LSTRING},
  198. {"wait", FOFS(wait), F_FLOAT},
  199. {"finaltime", FOFS(wait), F_FLOAT},//For dlight
  200. {"random", FOFS(random), F_FLOAT},
  201. {"FOV", FOFS(random), F_FLOAT},//for ref_tags and trigger_visibles
  202. {"count", FOFS(count), F_INT},
  203. {"bounceCount", FOFS(bounceCount), F_INT},
  204. {"health", FOFS(health), F_INT},
  205. {"friction", FOFS(health), F_INT},//For target_friction_change
  206. {"light", 0, F_IGNORE},
  207. {"dmg", FOFS(damage), F_INT},
  208. {"angles", FOFS(s.angles), F_VECTOR},
  209. {"angle", FOFS(s.angles), F_ANGLEHACK},
  210. {"modelAngles", FOFS(modelAngles), F_VECTOR},
  211. {"cameraGroup", FOFS(cameraGroup), F_LSTRING},
  212. {"radius", FOFS(radius), F_FLOAT},
  213. {"hiderange", FOFS(radius), F_FLOAT},//for triggers only
  214. {"starttime", FOFS(radius), F_FLOAT},//for dlight
  215. {"turfrange", FOFS(radius), F_FLOAT},//for sand creatures
  216. {"type", FOFS(count), F_FLOAT},//for fx_crew_beam_in
  217. {"fxfile", FOFS(fxFile), F_LSTRING},
  218. {"fxfile2", FOFS(cameraGroup), F_LSTRING},
  219. {"noVisTime", FOFS(endFrame), F_INT},//for NPC_Vehicle
  220. {"endFrame", FOFS(endFrame), F_INT},//for func_usable shader animation
  221. {"linear", FOFS(alt_fire), F_INT},//for movers to use linear movement
  222. {"weapon",FOFS(paintarget),F_LSTRING},//for misc_weapon_shooter only
  223. //Script parms - will this handle clamping to 16 or whatever length of parm[0] is?
  224. {"parm1", 0, F_PARM1},
  225. {"parm2", 0, F_PARM2},
  226. {"parm3", 0, F_PARM3},
  227. {"parm4", 0, F_PARM4},
  228. {"parm5", 0, F_PARM5},
  229. {"parm6", 0, F_PARM6},
  230. {"parm7", 0, F_PARM7},
  231. {"parm8", 0, F_PARM8},
  232. {"parm9", 0, F_PARM9},
  233. {"parm10", 0, F_PARM10},
  234. {"parm11", 0, F_PARM11},
  235. {"parm12", 0, F_PARM12},
  236. {"parm13", 0, F_PARM13},
  237. {"parm14", 0, F_PARM14},
  238. {"parm15", 0, F_PARM15},
  239. {"parm16", 0, F_PARM16},
  240. //{"noTED", FOFS(s.eFlags), F_FLAG},
  241. //MCG - Begin
  242. //extra fields for ents
  243. {"delay", FOFS(delay), F_INT},
  244. {"sounds", FOFS(sounds), F_INT},
  245. {"closetarget", FOFS(closetarget), F_LSTRING},//for doors
  246. {"opentarget", FOFS(opentarget), F_LSTRING},//for doors
  247. {"paintarget", FOFS(paintarget), F_LSTRING},//for doors
  248. {"soundGroup", FOFS(paintarget), F_LSTRING},//for target_speakers
  249. {"backwardstarget", FOFS(paintarget), F_LSTRING},//for trigger_bidirectional
  250. {"splashDamage", FOFS(splashDamage), F_INT},
  251. {"splashRadius", FOFS(splashRadius), F_INT},
  252. //Script stuff
  253. {"spawnscript", FOFS(behaviorSet[BSET_SPAWN]), F_LSTRING},//name of script to run
  254. {"usescript", FOFS(behaviorSet[BSET_USE]), F_LSTRING},//name of script to run
  255. {"awakescript", FOFS(behaviorSet[BSET_AWAKE]), F_LSTRING},//name of script to run
  256. {"angerscript", FOFS(behaviorSet[BSET_ANGER]), F_LSTRING},//name of script to run
  257. {"attackscript", FOFS(behaviorSet[BSET_ATTACK]), F_LSTRING},//name of script to run
  258. {"victoryscript", FOFS(behaviorSet[BSET_VICTORY]), F_LSTRING},//name of script to run
  259. {"lostenemyscript", FOFS(behaviorSet[BSET_LOSTENEMY]), F_LSTRING},//name of script to run
  260. {"painscript", FOFS(behaviorSet[BSET_PAIN]), F_LSTRING},//name of script to run
  261. {"fleescript", FOFS(behaviorSet[BSET_FLEE]), F_LSTRING},//name of script to run
  262. {"deathscript", FOFS(behaviorSet[BSET_DEATH]), F_LSTRING},//name of script to run
  263. {"delayscript", FOFS(behaviorSet[BSET_DELAYED]), F_LSTRING},//name of script to run
  264. {"delayscripttime", FOFS(delayScriptTime), F_INT},//name of script to run
  265. {"blockedscript", FOFS(behaviorSet[BSET_BLOCKED]), F_LSTRING},//name of script to run
  266. {"ffirescript", FOFS(behaviorSet[BSET_FFIRE]), F_LSTRING},//name of script to run
  267. {"ffdeathscript", FOFS(behaviorSet[BSET_FFDEATH]), F_LSTRING},//name of script to run
  268. {"mindtrickscript", FOFS(behaviorSet[BSET_MINDTRICK]), F_LSTRING},//name of script to run
  269. {"script_targetname", FOFS(script_targetname), F_LSTRING},//scripts look for this when "affecting"
  270. //For NPCs
  271. //{"playerTeam", FOFS(playerTeam), F_INT},
  272. //{"enemyTeam", FOFS(enemyTeam), F_INT},
  273. {"NPC_targetname", FOFS(NPC_targetname), F_LSTRING},
  274. {"NPC_target", FOFS(NPC_target), F_LSTRING},
  275. {"NPC_target2", FOFS(target2), F_LSTRING},//NPC_spawner only
  276. {"NPC_target4", FOFS(target4), F_LSTRING},//NPC_spawner only
  277. {"NPC_type", FOFS(NPC_type), F_LSTRING},
  278. {"ownername", FOFS(ownername), F_LSTRING},
  279. //for saber
  280. {"saberType", FOFS(NPC_type), F_LSTRING},
  281. {"saberColor", FOFS(NPC_targetname), F_LSTRING},
  282. {"saberSolo", FOFS(alt_fire), F_INT},
  283. //freaky camera shit
  284. {"startRGBA", FOFS(startRGBA), F_VECTOR4},
  285. {"finalRGBA", FOFS(finalRGBA), F_VECTOR4},
  286. //MCG - End
  287. {"soundSet", FOFS(soundSet), F_LSTRING},
  288. {"mass", FOFS(mass), F_FLOAT}, //really only used for pushable misc_model_breakables
  289. //q3map stuff
  290. {"scale", 0, F_IGNORE},
  291. {"modelscale", 0, F_IGNORE},
  292. {"modelscale_vec", 0, F_IGNORE},
  293. {"style", 0, F_IGNORE},
  294. {"lip", 0, F_IGNORE},
  295. {"switch_style", 0, F_IGNORE},
  296. {"height", 0, F_IGNORE},
  297. {"noise", 0, F_IGNORE}, //SP_target_speaker
  298. {"gravity", 0, F_IGNORE}, //SP_target_gravity_change
  299. {"storyhead", 0, F_IGNORE}, //SP_target_level_change
  300. {"tier_storyinfo", 0, F_IGNORE}, //SP_target_level_change
  301. {"zoffset", 0, F_IGNORE}, //used by misc_model_static
  302. {"music", 0, F_IGNORE}, //used by target_play_music
  303. {"forcevisible", 0, F_IGNORE}, //for force sight on multiple model entities
  304. {"redcrosshair", 0, F_IGNORE}, //for red crosshairs on breakables
  305. {"nodelay", 0, F_IGNORE}, //for Reborn & Cultist NPCs
  306. {NULL}
  307. };
  308. typedef struct {
  309. char *name;
  310. void (*spawn)(gentity_t *ent);
  311. } spawn_t;
  312. void SP_info_player_start (gentity_t *ent);
  313. void SP_info_player_deathmatch (gentity_t *ent);
  314. void SP_info_player_intermission (gentity_t *ent);
  315. void SP_info_firstplace(gentity_t *ent);
  316. void SP_info_secondplace(gentity_t *ent);
  317. void SP_info_thirdplace(gentity_t *ent);
  318. void SP_func_plat (gentity_t *ent);
  319. void SP_func_static (gentity_t *ent);
  320. void SP_func_rotating (gentity_t *ent);
  321. void SP_func_bobbing (gentity_t *ent);
  322. void SP_func_breakable (gentity_t *self);
  323. void SP_func_glass( gentity_t *self );
  324. void SP_func_pendulum( gentity_t *ent );
  325. void SP_func_button (gentity_t *ent);
  326. void SP_func_door (gentity_t *ent);
  327. void SP_func_train (gentity_t *ent);
  328. void SP_func_timer (gentity_t *self);
  329. void SP_func_wall (gentity_t *ent);
  330. void SP_func_usable( gentity_t *self );
  331. void SP_rail_mover( gentity_t *self );
  332. void SP_rail_track( gentity_t *self );
  333. void SP_rail_lane( gentity_t *self );
  334. void SP_trigger_always (gentity_t *ent);
  335. void SP_trigger_multiple (gentity_t *ent);
  336. void SP_trigger_once (gentity_t *ent);
  337. void SP_trigger_push (gentity_t *ent);
  338. void SP_trigger_teleport (gentity_t *ent);
  339. void SP_trigger_hurt (gentity_t *ent);
  340. void SP_trigger_bidirectional (gentity_t *ent);
  341. void SP_trigger_entdist (gentity_t *self);
  342. void SP_trigger_location( gentity_t *ent );
  343. void SP_trigger_visible( gentity_t *self );
  344. void SP_trigger_space(gentity_t *self);
  345. void SP_trigger_shipboundary(gentity_t *self);
  346. void SP_target_give (gentity_t *ent);
  347. void SP_target_delay (gentity_t *ent);
  348. void SP_target_speaker (gentity_t *ent);
  349. void SP_target_print (gentity_t *ent);
  350. void SP_target_laser (gentity_t *self);
  351. void SP_target_character (gentity_t *ent);
  352. void SP_target_score( gentity_t *ent );
  353. void SP_target_teleporter( gentity_t *ent );
  354. void SP_target_relay (gentity_t *ent);
  355. void SP_target_kill (gentity_t *ent);
  356. void SP_target_position (gentity_t *ent);
  357. void SP_target_location (gentity_t *ent);
  358. void SP_target_push (gentity_t *ent);
  359. void SP_target_random (gentity_t *self);
  360. void SP_target_counter (gentity_t *self);
  361. void SP_target_scriptrunner (gentity_t *self);
  362. void SP_target_interest (gentity_t *self);
  363. void SP_target_activate (gentity_t *self);
  364. void SP_target_deactivate (gentity_t *self);
  365. void SP_target_gravity_change( gentity_t *self );
  366. void SP_target_friction_change( gentity_t *self );
  367. void SP_target_level_change( gentity_t *self );
  368. void SP_target_change_parm( gentity_t *self );
  369. void SP_target_play_music( gentity_t *self );
  370. void SP_target_autosave( gentity_t *self );
  371. void SP_target_secret( gentity_t *self );
  372. void SP_light (gentity_t *self);
  373. void SP_info_null (gentity_t *self);
  374. void SP_info_notnull (gentity_t *self);
  375. void SP_path_corner (gentity_t *self);
  376. void SP_misc_teleporter (gentity_t *self);
  377. void SP_misc_teleporter_dest (gentity_t *self);
  378. void SP_misc_model(gentity_t *ent);
  379. void SP_misc_model_static(gentity_t *ent);
  380. void SP_misc_turret (gentity_t *base);
  381. void SP_misc_ns_turret (gentity_t *base);
  382. void SP_laser_arm (gentity_t *base);
  383. void SP_misc_ion_cannon( gentity_t *ent );
  384. void SP_misc_maglock( gentity_t *ent );
  385. void SP_misc_panel_turret( gentity_t *ent );
  386. void SP_misc_model_welder( gentity_t *ent );
  387. void SP_misc_model_jabba_cam( gentity_t *ent );
  388. void SP_misc_model_shield_power_converter( gentity_t *ent );
  389. void SP_misc_model_ammo_power_converter( gentity_t *ent );
  390. void SP_misc_model_bomb_planted( gentity_t *ent );
  391. void SP_misc_model_beacon( gentity_t *ent );
  392. void SP_misc_shield_floor_unit( gentity_t *ent );
  393. void SP_misc_ammo_floor_unit( gentity_t *ent );
  394. void SP_misc_model_gun_rack( gentity_t *ent );
  395. void SP_misc_model_ammo_rack( gentity_t *ent );
  396. void SP_misc_model_cargo_small( gentity_t *ent );
  397. void SP_misc_exploding_crate( gentity_t *ent );
  398. void SP_misc_gas_tank( gentity_t *ent );
  399. void SP_misc_crystal_crate( gentity_t *ent );
  400. void SP_misc_atst_drivable( gentity_t *ent );
  401. void SP_misc_model_breakable(gentity_t *ent);//stays as an ent
  402. void SP_misc_model_ghoul(gentity_t *ent);//stays as an ent
  403. void SP_misc_portal_camera(gentity_t *ent);
  404. void SP_misc_bsp(gentity_t *ent);
  405. void SP_terrain(gentity_t *ent);
  406. void SP_misc_skyportal (gentity_t *ent);
  407. void SP_misc_portal_surface(gentity_t *ent);
  408. void SP_misc_camera_focus (gentity_t *self);
  409. void SP_misc_camera_track (gentity_t *self);
  410. void SP_misc_dlight (gentity_t *ent);
  411. void SP_misc_security_panel (gentity_t *ent);
  412. void SP_misc_camera( gentity_t *ent );
  413. void SP_misc_spotlight( gentity_t *ent );
  414. void SP_shooter_rocket( gentity_t *ent );
  415. void SP_shooter_plasma( gentity_t *ent );
  416. void SP_shooter_grenade( gentity_t *ent );
  417. void SP_misc_replicator_item( gentity_t *ent );
  418. void SP_misc_trip_mine( gentity_t *self );
  419. void SP_PAS( gentity_t *ent );
  420. void SP_misc_weapon_shooter( gentity_t *self );
  421. void SP_misc_weather_zone( gentity_t *ent );
  422. //New spawn functions
  423. void SP_reference_tag ( gentity_t *ent );
  424. void SP_NPC_spawner( gentity_t *self );
  425. void SP_NPC_Vehicle( gentity_t *self );
  426. void SP_NPC_Player( gentity_t *self );
  427. void SP_NPC_Kyle( gentity_t *self );
  428. void SP_NPC_Lando( gentity_t *self );
  429. void SP_NPC_Jan( gentity_t *self );
  430. void SP_NPC_Luke( gentity_t *self );
  431. void SP_NPC_MonMothma( gentity_t *self );
  432. void SP_NPC_Rosh_Penin( gentity_t *self );
  433. void SP_NPC_Tavion( gentity_t *self );
  434. void SP_NPC_Tavion_New( gentity_t *self );
  435. void SP_NPC_Alora( gentity_t *self );
  436. void SP_NPC_Reelo( gentity_t *self );
  437. void SP_NPC_Galak( gentity_t *self );
  438. void SP_NPC_Desann( gentity_t *self );
  439. void SP_NPC_Rax( gentity_t *self );
  440. void SP_NPC_BobaFett( gentity_t *self );
  441. void SP_NPC_Ragnos( gentity_t *self );
  442. void SP_NPC_Lannik_Racto( gentity_t *self );
  443. void SP_NPC_Kothos( gentity_t *self );
  444. void SP_NPC_Chewbacca( gentity_t *self );
  445. void SP_NPC_Bartender( gentity_t *self );
  446. void SP_NPC_MorganKatarn( gentity_t *self );
  447. void SP_NPC_Jedi( gentity_t *self );
  448. void SP_NPC_Prisoner( gentity_t *self );
  449. void SP_NPC_Merchant( gentity_t *self );
  450. void SP_NPC_Rebel( gentity_t *self );
  451. void SP_NPC_Human_Merc( gentity_t *self );
  452. void SP_NPC_Stormtrooper( gentity_t *self );
  453. void SP_NPC_StormtrooperOfficer( gentity_t *self );
  454. void SP_NPC_Tie_Pilot( gentity_t *self );
  455. void SP_NPC_Snowtrooper( gentity_t *self );
  456. void SP_NPC_RocketTrooper( gentity_t *self);
  457. void SP_NPC_HazardTrooper( gentity_t *self);
  458. void SP_NPC_Ugnaught( gentity_t *self );
  459. void SP_NPC_Jawa( gentity_t *self );
  460. void SP_NPC_Gran( gentity_t *self );
  461. void SP_NPC_Rodian( gentity_t *self );
  462. void SP_NPC_Weequay( gentity_t *self );
  463. void SP_NPC_Trandoshan( gentity_t *self );
  464. void SP_NPC_Tusken( gentity_t *self );
  465. void SP_NPC_Noghri( gentity_t *self );
  466. void SP_NPC_SwampTrooper( gentity_t *self );
  467. void SP_NPC_Imperial( gentity_t *self );
  468. void SP_NPC_ImpWorker( gentity_t *self );
  469. void SP_NPC_BespinCop( gentity_t *self );
  470. void SP_NPC_Reborn( gentity_t *self );
  471. void SP_NPC_Reborn_New( gentity_t *self);
  472. void SP_NPC_Cultist( gentity_t *self );
  473. void SP_NPC_Cultist_Saber( gentity_t *self );
  474. void SP_NPC_Cultist_Saber_Powers( gentity_t *self );
  475. void SP_NPC_Cultist_Destroyer( gentity_t *self );
  476. void SP_NPC_Cultist_Commando( gentity_t *self );
  477. void SP_NPC_ShadowTrooper( gentity_t *self );
  478. void SP_NPC_Saboteur( gentity_t *self );
  479. void SP_NPC_Monster_Murjj( gentity_t *self );
  480. void SP_NPC_Monster_Swamp( gentity_t *self );
  481. void SP_NPC_Monster_Howler( gentity_t *self );
  482. void SP_NPC_Monster_Rancor( gentity_t *self );
  483. void SP_NPC_Monster_Mutant_Rancor( gentity_t *self );
  484. void SP_NPC_Monster_Wampa( gentity_t *self );
  485. void SP_NPC_Monster_Claw( gentity_t *self );
  486. void SP_NPC_Monster_Glider( gentity_t *self );
  487. void SP_NPC_Monster_Flier2( gentity_t *self );
  488. void SP_NPC_Monster_Lizard( gentity_t *self );
  489. void SP_NPC_Monster_Fish( gentity_t *self );
  490. void SP_NPC_Monster_Sand_Creature( gentity_t *self );
  491. void SP_NPC_MineMonster( gentity_t *self );
  492. void SP_NPC_Droid_Interrogator( gentity_t *self );
  493. void SP_NPC_Droid_Probe( gentity_t *self );
  494. void SP_NPC_Droid_Mark1( gentity_t *self );
  495. void SP_NPC_Droid_Mark2( gentity_t *self );
  496. void SP_NPC_Droid_ATST( gentity_t *self );
  497. void SP_NPC_Droid_Seeker( gentity_t *self );
  498. void SP_NPC_Droid_Remote( gentity_t *self );
  499. void SP_NPC_Droid_Sentry( gentity_t *self );
  500. void SP_NPC_Droid_Gonk( gentity_t *self );
  501. void SP_NPC_Droid_Mouse( gentity_t *self );
  502. void SP_NPC_Droid_R2D2( gentity_t *self );
  503. void SP_NPC_Droid_R5D2( gentity_t *self );
  504. void SP_NPC_Droid_Protocol( gentity_t *self );
  505. void SP_NPC_Droid_Assassin( gentity_t *self);
  506. void SP_NPC_Droid_Saber( gentity_t *self);
  507. void SP_waypoint (gentity_t *ent);
  508. void SP_waypoint_small (gentity_t *ent);
  509. void SP_waypoint_navgoal (gentity_t *ent);
  510. void SP_fx_runner( gentity_t *ent );
  511. void SP_fx_explosion_trail( gentity_t *ent );
  512. void SP_fx_target_beam( gentity_t *ent );
  513. void SP_fx_cloudlayer( gentity_t *ent );
  514. void SP_CreateSnow( gentity_t *ent );
  515. void SP_CreateRain( gentity_t *ent );
  516. void SP_CreateWind( gentity_t *ent );
  517. void SP_CreateWindZone( gentity_t *ent );
  518. // Added 10/20/02 by Aurelio Reis
  519. void SP_CreatePuffSystem( gentity_t *ent );
  520. void SP_object_cargo_barrel1( gentity_t *ent );
  521. void SP_point_combat (gentity_t *self);
  522. void SP_emplaced_eweb( gentity_t *self );
  523. void SP_emplaced_gun( gentity_t *self );
  524. void SP_misc_turbobattery( gentity_t *base );
  525. spawn_t spawns[] = {
  526. {"info_player_start", SP_info_player_start},
  527. {"info_player_deathmatch", SP_info_player_deathmatch},
  528. {"func_plat", SP_func_plat},
  529. {"func_button", SP_func_button},
  530. {"func_door", SP_func_door},
  531. {"func_static", SP_func_static},
  532. {"func_rotating", SP_func_rotating},
  533. {"func_bobbing", SP_func_bobbing},
  534. {"func_breakable", SP_func_breakable},
  535. {"func_pendulum", SP_func_pendulum},
  536. {"func_train", SP_func_train},
  537. {"func_timer", SP_func_timer}, // rename trigger_timer?
  538. {"func_wall", SP_func_wall},
  539. {"func_usable", SP_func_usable},
  540. {"func_glass", SP_func_glass},
  541. {"rail_mover", SP_rail_mover},
  542. {"rail_track", SP_rail_track},
  543. {"rail_lane", SP_rail_lane},
  544. {"trigger_always", SP_trigger_always},
  545. {"trigger_multiple", SP_trigger_multiple},
  546. {"trigger_once", SP_trigger_once},
  547. {"trigger_push", SP_trigger_push},
  548. {"trigger_teleport", SP_trigger_teleport},
  549. {"trigger_hurt", SP_trigger_hurt},
  550. {"trigger_bidirectional", SP_trigger_bidirectional},
  551. {"trigger_entdist", SP_trigger_entdist},
  552. {"trigger_location", SP_trigger_location},
  553. {"trigger_visible", SP_trigger_visible},
  554. {"trigger_space", SP_trigger_space},
  555. {"trigger_shipboundary", SP_trigger_shipboundary},
  556. {"target_give", SP_target_give},
  557. {"target_delay", SP_target_delay},
  558. {"target_speaker", SP_target_speaker},
  559. {"target_print", SP_target_print},
  560. {"target_laser", SP_target_laser},
  561. {"target_score", SP_target_score},
  562. {"target_teleporter", SP_target_teleporter},
  563. {"target_relay", SP_target_relay},
  564. {"target_kill", SP_target_kill},
  565. {"target_position", SP_target_position},
  566. {"target_location", SP_target_location},
  567. {"target_push", SP_target_push},
  568. {"target_random", SP_target_random},
  569. {"target_counter", SP_target_counter},
  570. {"target_scriptrunner", SP_target_scriptrunner},
  571. {"target_interest", SP_target_interest},
  572. {"target_activate", SP_target_activate},
  573. {"target_deactivate", SP_target_deactivate},
  574. {"target_gravity_change", SP_target_gravity_change},
  575. {"target_friction_change", SP_target_friction_change},
  576. {"target_level_change", SP_target_level_change},
  577. {"target_change_parm", SP_target_change_parm},
  578. {"target_play_music", SP_target_play_music},
  579. {"target_autosave", SP_target_autosave},
  580. {"target_secret", SP_target_secret},
  581. {"light", SP_light},
  582. {"info_null", SP_info_null},
  583. {"func_group", SP_info_null},
  584. {"info_notnull", SP_info_notnull}, // use target_position instead
  585. {"path_corner", SP_path_corner},
  586. {"misc_teleporter", SP_misc_teleporter},
  587. {"misc_teleporter_dest", SP_misc_teleporter_dest},
  588. {"misc_model", SP_misc_model},
  589. {"misc_model_static", SP_misc_model_static},
  590. {"misc_turret", SP_misc_turret},
  591. {"misc_ns_turret", SP_misc_ns_turret},
  592. {"misc_laser_arm", SP_laser_arm},
  593. {"misc_ion_cannon", SP_misc_ion_cannon},
  594. {"misc_sentry_turret", SP_PAS},
  595. {"misc_maglock", SP_misc_maglock},
  596. {"misc_weapon_shooter", SP_misc_weapon_shooter},
  597. {"misc_weather_zone", SP_misc_weather_zone},
  598. {"misc_model_ghoul", SP_misc_model_ghoul},
  599. {"misc_model_breakable", SP_misc_model_breakable},
  600. {"misc_portal_surface", SP_misc_portal_surface},
  601. {"misc_portal_camera", SP_misc_portal_camera},
  602. {"misc_bsp", SP_misc_bsp},
  603. {"terrain", SP_terrain},
  604. {"misc_skyportal", SP_misc_skyportal},
  605. {"misc_camera_focus", SP_misc_camera_focus},
  606. {"misc_camera_track", SP_misc_camera_track},
  607. {"misc_dlight", SP_misc_dlight},
  608. {"misc_replicator_item", SP_misc_replicator_item},
  609. {"misc_trip_mine", SP_misc_trip_mine},
  610. {"misc_security_panel", SP_misc_security_panel},
  611. {"misc_camera", SP_misc_camera},
  612. {"misc_spotlight", SP_misc_spotlight},
  613. {"misc_panel_turret", SP_misc_panel_turret},
  614. {"misc_model_welder", SP_misc_model_welder},
  615. {"misc_model_jabba_cam", SP_misc_model_jabba_cam},
  616. {"misc_model_shield_power_converter", SP_misc_model_shield_power_converter},
  617. {"misc_model_ammo_power_converter", SP_misc_model_ammo_power_converter},
  618. {"misc_model_bomb_planted", SP_misc_model_bomb_planted},
  619. {"misc_model_beacon", SP_misc_model_beacon},
  620. {"misc_shield_floor_unit", SP_misc_shield_floor_unit},
  621. {"misc_ammo_floor_unit", SP_misc_ammo_floor_unit},
  622. {"misc_model_gun_rack", SP_misc_model_gun_rack},
  623. {"misc_model_ammo_rack", SP_misc_model_ammo_rack},
  624. {"misc_model_cargo_small", SP_misc_model_cargo_small},
  625. {"misc_exploding_crate", SP_misc_exploding_crate},
  626. {"misc_gas_tank", SP_misc_gas_tank},
  627. {"misc_crystal_crate", SP_misc_crystal_crate},
  628. {"misc_atst_drivable", SP_misc_atst_drivable},
  629. {"shooter_rocket", SP_shooter_rocket},
  630. {"shooter_grenade", SP_shooter_grenade},
  631. {"shooter_plasma", SP_shooter_plasma},
  632. {"ref_tag", SP_reference_tag},
  633. //new NPC ents
  634. {"NPC_spawner", SP_NPC_spawner},
  635. {"NPC_Vehicle", SP_NPC_Vehicle },
  636. {"NPC_Player", SP_NPC_Player },
  637. {"NPC_Kyle", SP_NPC_Kyle },
  638. {"NPC_Lando", SP_NPC_Lando },
  639. {"NPC_Jan", SP_NPC_Jan },
  640. {"NPC_Luke", SP_NPC_Luke },
  641. {"NPC_MonMothma", SP_NPC_MonMothma },
  642. {"NPC_Rosh_Penin", SP_NPC_Rosh_Penin },
  643. {"NPC_Tavion", SP_NPC_Tavion },
  644. {"NPC_Tavion_New", SP_NPC_Tavion_New },
  645. {"NPC_Alora", SP_NPC_Alora },
  646. {"NPC_Reelo", SP_NPC_Reelo },
  647. {"NPC_Galak", SP_NPC_Galak },
  648. {"NPC_Desann", SP_NPC_Desann },
  649. {"NPC_Rax", SP_NPC_Rax },
  650. {"NPC_BobaFett", SP_NPC_BobaFett },
  651. {"NPC_Ragnos", SP_NPC_Ragnos },
  652. {"NPC_Lannik_Racto", SP_NPC_Lannik_Racto },
  653. {"NPC_Kothos", SP_NPC_Kothos },
  654. {"NPC_Chewbacca", SP_NPC_Chewbacca },
  655. {"NPC_Bartender", SP_NPC_Bartender },
  656. {"NPC_MorganKatarn", SP_NPC_MorganKatarn },
  657. {"NPC_Jedi", SP_NPC_Jedi },
  658. {"NPC_Prisoner", SP_NPC_Prisoner },
  659. {"NPC_Merchant", SP_NPC_Merchant },
  660. {"NPC_Rebel", SP_NPC_Rebel },
  661. {"NPC_Human_Merc", SP_NPC_Human_Merc },
  662. {"NPC_Stormtrooper", SP_NPC_Stormtrooper },
  663. {"NPC_StormtrooperOfficer", SP_NPC_StormtrooperOfficer },
  664. {"NPC_Tie_Pilot", SP_NPC_Tie_Pilot },
  665. {"NPC_Snowtrooper", SP_NPC_Snowtrooper },
  666. {"NPC_RocketTrooper", SP_NPC_RocketTrooper },
  667. {"NPC_HazardTrooper", SP_NPC_HazardTrooper },
  668. {"NPC_Ugnaught", SP_NPC_Ugnaught },
  669. {"NPC_Jawa", SP_NPC_Jawa },
  670. {"NPC_Gran", SP_NPC_Gran },
  671. {"NPC_Rodian", SP_NPC_Rodian },
  672. {"NPC_Weequay", SP_NPC_Weequay },
  673. {"NPC_Trandoshan", SP_NPC_Trandoshan },
  674. {"NPC_Tusken", SP_NPC_Tusken },
  675. {"NPC_Noghri", SP_NPC_Noghri },
  676. {"NPC_SwampTrooper", SP_NPC_SwampTrooper },
  677. {"NPC_Imperial", SP_NPC_Imperial },
  678. {"NPC_ImpWorker", SP_NPC_ImpWorker },
  679. {"NPC_BespinCop", SP_NPC_BespinCop },
  680. {"NPC_Reborn", SP_NPC_Reborn },
  681. {"NPC_Reborn_New", SP_NPC_Reborn_New },
  682. {"NPC_Cultist", SP_NPC_Cultist },
  683. {"NPC_Cultist_Saber", SP_NPC_Cultist_Saber },
  684. {"NPC_Cultist_Saber_Powers", SP_NPC_Cultist_Saber_Powers },
  685. {"NPC_Cultist_Destroyer", SP_NPC_Cultist_Destroyer },
  686. {"NPC_Cultist_Commando", SP_NPC_Cultist_Commando },
  687. {"NPC_ShadowTrooper", SP_NPC_ShadowTrooper },
  688. {"NPC_Saboteur", SP_NPC_Saboteur },
  689. {"NPC_Monster_Murjj", SP_NPC_Monster_Murjj },
  690. {"NPC_Monster_Swamp", SP_NPC_Monster_Swamp },
  691. {"NPC_Monster_Howler", SP_NPC_Monster_Howler },
  692. {"NPC_Monster_Rancor", SP_NPC_Monster_Rancor },
  693. {"NPC_Monster_Mutant_Rancor", SP_NPC_Monster_Mutant_Rancor },
  694. {"NPC_Monster_Wampa", SP_NPC_Monster_Wampa },
  695. {"NPC_MineMonster", SP_NPC_MineMonster },
  696. {"NPC_Monster_Claw", SP_NPC_Monster_Claw },
  697. {"NPC_Monster_Glider", SP_NPC_Monster_Glider },
  698. {"NPC_Monster_Flier2", SP_NPC_Monster_Flier2 },
  699. {"NPC_Monster_Lizard", SP_NPC_Monster_Lizard },
  700. {"NPC_Monster_Fish", SP_NPC_Monster_Fish },
  701. {"NPC_Monster_Sand_Creature", SP_NPC_Monster_Sand_Creature },
  702. {"NPC_Droid_Interrogator", SP_NPC_Droid_Interrogator },
  703. {"NPC_Droid_Probe", SP_NPC_Droid_Probe },
  704. {"NPC_Droid_Mark1", SP_NPC_Droid_Mark1 },
  705. {"NPC_Droid_Mark2", SP_NPC_Droid_Mark2 },
  706. {"NPC_Droid_ATST", SP_NPC_Droid_ATST },
  707. {"NPC_Droid_Seeker", SP_NPC_Droid_Seeker },
  708. {"NPC_Droid_Remote", SP_NPC_Droid_Remote },
  709. {"NPC_Droid_Sentry", SP_NPC_Droid_Sentry },
  710. {"NPC_Droid_Gonk", SP_NPC_Droid_Gonk },
  711. {"NPC_Droid_Mouse", SP_NPC_Droid_Mouse },
  712. {"NPC_Droid_R2D2", SP_NPC_Droid_R2D2 },
  713. {"NPC_Droid_R5D2", SP_NPC_Droid_R5D2 },
  714. {"NPC_Droid_Protocol", SP_NPC_Droid_Protocol },
  715. {"NPC_Droid_Assassin", SP_NPC_Droid_Assassin },
  716. {"NPC_Droid_Saber", SP_NPC_Droid_Saber },
  717. //rwwFIXMEFIXME: Faked for testing NPCs (another other things) in RMG with sof2 assets
  718. {"NPC_Colombian_Soldier", SP_NPC_Reborn },
  719. {"NPC_Colombian_Rebel", SP_NPC_Reborn },
  720. {"NPC_Colombian_EmplacedGunner", SP_NPC_ShadowTrooper },
  721. {"NPC_Manuel_Vergara_RMG", SP_NPC_Desann },
  722. // {"info_NPCnav", SP_waypoint},
  723. {"waypoint", SP_waypoint},
  724. {"waypoint_small", SP_waypoint_small},
  725. {"waypoint_navgoal", SP_waypoint_navgoal},
  726. {"fx_runner", SP_fx_runner},
  727. {"fx_explosion_trail", SP_fx_explosion_trail},
  728. {"fx_target_beam", SP_fx_target_beam},
  729. {"fx_cloudlayer", SP_fx_cloudlayer},
  730. {"fx_rain", SP_CreateRain},
  731. {"fx_wind", SP_CreateWind},
  732. {"fx_snow", SP_CreateSnow},
  733. {"fx_puff", SP_CreatePuffSystem},
  734. {"fx_wind_zone", SP_CreateWindZone},
  735. {"object_cargo_barrel1", SP_object_cargo_barrel1},
  736. {"point_combat", SP_point_combat},
  737. {"emplaced_gun", SP_emplaced_gun},
  738. {"emplaced_eweb", SP_emplaced_eweb},
  739. {NULL, NULL}
  740. };
  741. /*
  742. ===============
  743. G_CallSpawn
  744. Finds the spawn function for the entity and calls it,
  745. returning qfalse if not found
  746. ===============
  747. */
  748. qboolean G_CallSpawn( gentity_t *ent ) {
  749. spawn_t *s;
  750. gitem_t *item;
  751. if ( !ent->classname ) {
  752. gi.Printf (S_COLOR_RED"G_CallSpawn: NULL classname\n");
  753. return qfalse;
  754. }
  755. // check item spawn functions
  756. for ( item=bg_itemlist+1 ; item->classname ; item++ ) {
  757. if ( !strcmp(item->classname, ent->classname) ) {
  758. // found it
  759. G_SpawnItem( ent, item );
  760. return qtrue;
  761. }
  762. }
  763. // check normal spawn functions
  764. for ( s=spawns ; s->name ; s++ ) {
  765. if ( !strcmp(s->name, ent->classname) ) {
  766. // found it
  767. s->spawn(ent);
  768. return qtrue;
  769. }
  770. }
  771. char* str;
  772. G_SpawnString( "origin", "?", &str );
  773. gi.Printf (S_COLOR_RED"ERROR: %s is not a spawn function @(%s)\n", ent->classname, str);
  774. delayedShutDown = level.time + 100;
  775. return qfalse;
  776. }
  777. /*
  778. =============
  779. G_NewString
  780. Builds a copy of the string, translating \n to real linefeeds
  781. so message texts can be multi-line
  782. =============
  783. */
  784. char *G_NewString( const char *string ) {
  785. char *newb, *new_p;
  786. int i,l;
  787. if(!string || !string[0])
  788. {
  789. //gi.Printf(S_COLOR_RED"Error: G_NewString called with NULL string!\n");
  790. return NULL;
  791. }
  792. l = strlen(string) + 1;
  793. newb = (char *) G_Alloc( l );
  794. new_p = newb;
  795. // turn \n into a real linefeed
  796. for ( i=0 ; i< l ; i++ ) {
  797. if (string[i] == '\\' && i < l-1) {
  798. i++;
  799. if (string[i] == 'n') {
  800. *new_p++ = '\n';
  801. } else {
  802. *new_p++ = '\\';
  803. }
  804. } else {
  805. *new_p++ = string[i];
  806. }
  807. }
  808. return newb;
  809. }
  810. /*
  811. ===============
  812. G_ParseField
  813. Takes a key/value pair and sets the binary values
  814. in a gentity
  815. ===============
  816. */
  817. void Q3_SetParm (int entID, int parmNum, const char *parmValue);
  818. void G_ParseField( const char *key, const char *value, gentity_t *ent ) {
  819. field_t *f;
  820. byte *b;
  821. float v;
  822. vec3_t vec;
  823. vec4_t vec4;
  824. for ( f=fields ; f->name ; f++ ) {
  825. if ( !Q_stricmp(f->name, key) ) {
  826. // found it
  827. b = (byte *)ent;
  828. switch( f->type ) {
  829. case F_LSTRING:
  830. *(char **)(b+f->ofs) = G_NewString (value);
  831. break;
  832. case F_VECTOR:
  833. {
  834. int _iFieldsRead = sscanf (value, "%f %f %f", &vec[0], &vec[1], &vec[2]);
  835. assert(_iFieldsRead==3);
  836. if (_iFieldsRead!=3)
  837. {
  838. gi.Printf (S_COLOR_YELLOW"G_ParseField: VEC3 sscanf() failed to read 3 floats ('angle' key bug?)\n");
  839. delayedShutDown = level.time + 100;
  840. }
  841. ((float *)(b+f->ofs))[0] = vec[0];
  842. ((float *)(b+f->ofs))[1] = vec[1];
  843. ((float *)(b+f->ofs))[2] = vec[2];
  844. break;
  845. }
  846. case F_VECTOR4:
  847. {
  848. int _iFieldsRead = sscanf (value, "%f %f %f %f", &vec4[0], &vec4[1], &vec4[2], &vec4[3]);
  849. assert(_iFieldsRead==4);
  850. if (_iFieldsRead!=4)
  851. {
  852. gi.Printf (S_COLOR_YELLOW"G_ParseField: VEC4 sscanf() failed to read 4 floats\n");
  853. delayedShutDown = level.time + 100;
  854. }
  855. ((float *)(b+f->ofs))[0] = vec4[0];
  856. ((float *)(b+f->ofs))[1] = vec4[1];
  857. ((float *)(b+f->ofs))[2] = vec4[2];
  858. ((float *)(b+f->ofs))[3] = vec4[3];
  859. break;
  860. }
  861. case F_INT:
  862. *(int *)(b+f->ofs) = atoi(value);
  863. break;
  864. case F_FLOAT:
  865. *(float *)(b+f->ofs) = atof(value);
  866. break;
  867. case F_ANGLEHACK:
  868. v = atof(value);
  869. ((float *)(b+f->ofs))[0] = 0;
  870. ((float *)(b+f->ofs))[1] = v;
  871. ((float *)(b+f->ofs))[2] = 0;
  872. break;
  873. case F_PARM1:
  874. case F_PARM2:
  875. case F_PARM3:
  876. case F_PARM4:
  877. case F_PARM5:
  878. case F_PARM6:
  879. case F_PARM7:
  880. case F_PARM8:
  881. case F_PARM9:
  882. case F_PARM10:
  883. case F_PARM11:
  884. case F_PARM12:
  885. case F_PARM13:
  886. case F_PARM14:
  887. case F_PARM15:
  888. case F_PARM16:
  889. Q3_SetParm( ent->s.number, (f->type - F_PARM1), (char *) value );
  890. break;
  891. case F_FLAG:
  892. {//try to find the proper flag for that key:
  893. int flag = GetIDForString ( flagTable, key );
  894. if ( flag > 0 )
  895. {
  896. G_SpawnFlag( key, flag, (int *)(b+f->ofs) );
  897. }
  898. else
  899. {
  900. #ifndef FINAL_BUILD
  901. gi.Printf (S_COLOR_YELLOW"WARNING: G_ParseField: can't find flag for key %s\n", key);
  902. #endif
  903. }
  904. }
  905. break;
  906. default:
  907. case F_IGNORE:
  908. break;
  909. }
  910. return;
  911. }
  912. }
  913. #ifndef FINAL_BUILD
  914. //didn't find it?
  915. if (key[0]!='_')
  916. {
  917. gi.Printf ( S_COLOR_YELLOW"WARNING: G_ParseField: no such field: %s\n", key );
  918. }
  919. #endif
  920. }
  921. static qboolean SpawnForCurrentDifficultySetting( gentity_t *ent )
  922. {
  923. extern cvar_t *com_buildScript;
  924. if (com_buildScript->integer) { //always spawn when building a pak file
  925. return qtrue;
  926. }
  927. if ( ent->spawnflags & ( 1 << (8 + g_spskill->integer )) ) {// easy -256 medium -512 hard -1024
  928. return qfalse;
  929. } else {
  930. return qtrue;
  931. }
  932. }
  933. /*
  934. ===================
  935. G_SpawnGEntityFromSpawnVars
  936. Spawn an entity and fill in all of the level fields from
  937. level.spawnVars[], then call the class specfic spawn function
  938. ===================
  939. */
  940. void G_SpawnGEntityFromSpawnVars( void ) {
  941. int i;
  942. gentity_t *ent;
  943. // get the next free entity
  944. ent = G_Spawn();
  945. for ( i = 0 ; i < numSpawnVars ; i++ ) {
  946. G_ParseField( spawnVars[i][0], spawnVars[i][1], ent );
  947. }
  948. G_SpawnInt( "notsingle", "0", &i );
  949. if ( i || !SpawnForCurrentDifficultySetting( ent ) ) {
  950. G_FreeEntity( ent );
  951. return;
  952. }
  953. // move editor origin to pos
  954. VectorCopy( ent->s.origin, ent->s.pos.trBase );
  955. VectorCopy( ent->s.origin, ent->currentOrigin );
  956. // if we didn't get a classname, don't bother spawning anything
  957. if ( !G_CallSpawn( ent ) ) {
  958. G_FreeEntity( ent );
  959. return;
  960. }
  961. //Tag on the ICARUS scripting information only to valid recipients
  962. if ( Quake3Game()->ValidEntity( ent ) )
  963. {
  964. Quake3Game()->InitEntity( ent ); //ICARUS_InitEnt( ent );
  965. if ( ent->classname && ent->classname[0] )
  966. {
  967. if ( Q_strncmp( "NPC_", ent->classname, 4 ) != 0 )
  968. {//Not an NPC_spawner
  969. G_ActivateBehavior( ent, BSET_SPAWN );
  970. }
  971. }
  972. }
  973. }
  974. void G_SpawnSubBSPGEntityFromSpawnVars( vec3_t posOffset, vec3_t angOffset ) {
  975. int i;
  976. gentity_t *ent;
  977. // get the next free entity
  978. ent = G_Spawn();
  979. for ( i = 0 ; i < numSpawnVars ; i++ ) {
  980. G_ParseField( spawnVars[i][0], spawnVars[i][1], ent );
  981. }
  982. G_SpawnInt( "notsingle", "0", &i );
  983. if ( i || !SpawnForCurrentDifficultySetting( ent ) ) {
  984. G_FreeEntity( ent );
  985. return;
  986. }
  987. VectorAdd(ent->s.origin, posOffset, ent->s.origin);
  988. VectorAdd(ent->s.angles, angOffset, ent->s.angles);
  989. VectorCopy(ent->s.angles, ent->s.apos.trBase);
  990. VectorCopy(ent->s.angles, ent->currentAngles);
  991. // move editor origin to pos
  992. VectorCopy( ent->s.origin, ent->s.pos.trBase );
  993. VectorCopy( ent->s.origin, ent->currentOrigin );
  994. // if we didn't get a classname, don't bother spawning anything
  995. if ( !G_CallSpawn( ent ) ) {
  996. G_FreeEntity( ent );
  997. return;
  998. }
  999. //Tag on the ICARUS scripting information only to valid recipients
  1000. if ( Quake3Game()->ValidEntity( ent ) )
  1001. {
  1002. Quake3Game()->InitEntity( ent ); // ICARUS_InitEnt( ent );
  1003. if ( ent->classname && ent->classname[0] )
  1004. {
  1005. if ( Q_strncmp( "NPC_", ent->classname, 4 ) != 0 )
  1006. {//Not an NPC_spawner
  1007. G_ActivateBehavior( ent, BSET_SPAWN );
  1008. }
  1009. }
  1010. }
  1011. }
  1012. /*
  1013. ====================
  1014. G_AddSpawnVarToken
  1015. ====================
  1016. */
  1017. char *G_AddSpawnVarToken( const char *string ) {
  1018. int l;
  1019. char *dest;
  1020. l = strlen( string );
  1021. if ( numSpawnVarChars + l + 1 > MAX_SPAWN_VARS_CHARS ) {
  1022. G_Error( "G_AddSpawnVarToken: MAX_SPAWN_VARS" );
  1023. }
  1024. dest = spawnVarChars + numSpawnVarChars;
  1025. memcpy( dest, string, l+1 );
  1026. numSpawnVarChars += l + 1;
  1027. return dest;
  1028. }
  1029. /*
  1030. ====================
  1031. G_ParseSpawnVars
  1032. Parses a brace bounded set of key / value pairs out of the
  1033. level's entity strings into level.spawnVars[]
  1034. This does not actually spawn an entity.
  1035. ====================
  1036. */
  1037. qboolean G_ParseSpawnVars( const char **data ) {
  1038. char keyname[MAX_STRING_CHARS];
  1039. const char *com_token;
  1040. numSpawnVars = 0;
  1041. numSpawnVarChars = 0;
  1042. // parse the opening brace
  1043. com_token = COM_Parse( data );
  1044. if ( !*data ) {
  1045. // end of spawn string
  1046. return qfalse;
  1047. }
  1048. if ( com_token[0] != '{' ) {
  1049. G_Error( "G_ParseSpawnVars: found %s when expecting {",com_token );
  1050. }
  1051. // go through all the key / value pairs
  1052. while ( 1 ) {
  1053. // parse key
  1054. com_token = COM_Parse( data );
  1055. if ( com_token[0] == '}' ) {
  1056. break;
  1057. }
  1058. if ( !data ) {
  1059. G_Error( "G_ParseSpawnVars: EOF without closing brace" );
  1060. }
  1061. Q_strncpyz( keyname, com_token, sizeof(keyname) );
  1062. // parse value
  1063. com_token = COM_Parse( data );
  1064. if ( com_token[0] == '}' ) {
  1065. G_Error( "G_ParseSpawnVars: closing brace without data" );
  1066. }
  1067. if ( !data ) {
  1068. G_Error( "G_ParseSpawnVars: EOF without closing brace" );
  1069. }
  1070. if ( numSpawnVars == MAX_SPAWN_VARS ) {
  1071. G_Error( "G_ParseSpawnVars: MAX_SPAWN_VARS" );
  1072. }
  1073. spawnVars[ numSpawnVars ][0] = G_AddSpawnVarToken( keyname );
  1074. spawnVars[ numSpawnVars ][1] = G_AddSpawnVarToken( com_token );
  1075. numSpawnVars++;
  1076. }
  1077. return qtrue;
  1078. }
  1079. static char *defaultStyles[LS_NUM_STYLES][3] =
  1080. {
  1081. { // 0 normal
  1082. "z",
  1083. "z",
  1084. "z"
  1085. },
  1086. { // 1 FLICKER (first variety)
  1087. "mmnmmommommnonmmonqnmmo",
  1088. "mmnmmommommnonmmonqnmmo",
  1089. "mmnmmommommnonmmonqnmmo"
  1090. },
  1091. { // 2 SLOW STRONG PULSE
  1092. "abcdefghijklmnopqrstuvwxyzyxwvutsrqponmlkjihgfedcb",
  1093. "abcdefghijklmnopqrstuvwxyzyxwvutsrqponmlkjihgfedcb",
  1094. "abcdefghijklmnopqrstuvwxyzyxwvutsrqponmlkjihgfedcb"
  1095. },
  1096. { // 3 CANDLE (first variety)
  1097. "mmmmmaaaaammmmmaaaaaabcdefgabcdefg",
  1098. "mmmmmaaaaammmmmaaaaaabcdefgabcdefg",
  1099. "mmmmmaaaaammmmmaaaaaabcdefgabcdefg"
  1100. },
  1101. { // 4 FAST STROBE
  1102. "mamamamamama",
  1103. "mamamamamama",
  1104. "mamamamamama"
  1105. },
  1106. { // 5 GENTLE PULSE 1
  1107. "jklmnopqrstuvwxyzyxwvutsrqponmlkj",
  1108. "jklmnopqrstuvwxyzyxwvutsrqponmlkj",
  1109. "jklmnopqrstuvwxyzyxwvutsrqponmlkj"
  1110. },
  1111. { // 6 FLICKER (second variety)
  1112. "nmonqnmomnmomomno",
  1113. "nmonqnmomnmomomno",
  1114. "nmonqnmomnmomomno"
  1115. },
  1116. { // 7 CANDLE (second variety)
  1117. "mmmaaaabcdefgmmmmaaaammmaamm",
  1118. "mmmaaaabcdefgmmmmaaaammmaamm",
  1119. "mmmaaaabcdefgmmmmaaaammmaamm"
  1120. },
  1121. { // 8 CANDLE (third variety)
  1122. "mmmaaammmaaammmabcdefaaaammmmabcdefmmmaaaa",
  1123. "mmmaaammmaaammmabcdefaaaammmmabcdefmmmaaaa",
  1124. "mmmaaammmaaammmabcdefaaaammmmabcdefmmmaaaa"
  1125. },
  1126. { // 9 SLOW STROBE (fourth variety)
  1127. "aaaaaaaazzzzzzzz",
  1128. "aaaaaaaazzzzzzzz",
  1129. "aaaaaaaazzzzzzzz"
  1130. },
  1131. { // 10 FLUORESCENT FLICKER
  1132. "mmamammmmammamamaaamammma",
  1133. "mmamammmmammamamaaamammma",
  1134. "mmamammmmammamamaaamammma"
  1135. },
  1136. { // 11 SLOW PULSE NOT FADE TO BLACK
  1137. "abcdefghijklmnopqrrqponmlkjihgfedcba",
  1138. "abcdefghijklmnopqrrqponmlkjihgfedcba",
  1139. "abcdefghijklmnopqrrqponmlkjihgfedcba"
  1140. },
  1141. { // 12 FAST PULSE FOR JEREMY
  1142. "mkigegik",
  1143. "mkigegik",
  1144. "mkigegik"
  1145. },
  1146. { // 13 Test Blending
  1147. "abcdefghijklmqrstuvwxyz",
  1148. "zyxwvutsrqmlkjihgfedcba",
  1149. "aammbbzzccllcckkffyyggp"
  1150. },
  1151. { // 14
  1152. "",
  1153. "",
  1154. ""
  1155. },
  1156. { // 15
  1157. "",
  1158. "",
  1159. ""
  1160. },
  1161. { // 16
  1162. "",
  1163. "",
  1164. ""
  1165. },
  1166. { // 17
  1167. "",
  1168. "",
  1169. ""
  1170. },
  1171. { // 18
  1172. "",
  1173. "",
  1174. ""
  1175. },
  1176. { // 19
  1177. "",
  1178. "",
  1179. ""
  1180. },
  1181. { // 20
  1182. "",
  1183. "",
  1184. ""
  1185. },
  1186. { // 21
  1187. "",
  1188. "",
  1189. ""
  1190. },
  1191. { // 22
  1192. "",
  1193. "",
  1194. ""
  1195. },
  1196. { // 23
  1197. "",
  1198. "",
  1199. ""
  1200. },
  1201. { // 24
  1202. "",
  1203. "",
  1204. ""
  1205. },
  1206. { // 25
  1207. "",
  1208. "",
  1209. ""
  1210. },
  1211. { // 26
  1212. "",
  1213. "",
  1214. ""
  1215. },
  1216. { // 27
  1217. "",
  1218. "",
  1219. ""
  1220. },
  1221. { // 28
  1222. "",
  1223. "",
  1224. ""
  1225. },
  1226. { // 29
  1227. "",
  1228. "",
  1229. ""
  1230. },
  1231. { // 30
  1232. "",
  1233. "",
  1234. ""
  1235. },
  1236. { // 31
  1237. "",
  1238. "",
  1239. ""
  1240. }
  1241. };
  1242. /*QUAKED worldspawn (0 0 0) ?
  1243. Every map should have exactly one worldspawn.
  1244. "music" path to WAV or MP3 files (e.g. "music\intro.mp3 music\loopfile.mp3")
  1245. "gravity" 800 is default gravity
  1246. "message" Text to print during connection
  1247. "soundSet" Ambient sound set to play
  1248. "spawnscript" runs this script
  1249. BSP Options
  1250. "gridsize" size of lighting grid to "X Y Z". default="64 64 128"
  1251. "ambient" amount of global light to add to each surf (uses _color)
  1252. "chopsize" value for bsp on the maximum polygon / portal size
  1253. "distancecull" value for vis for the maximum viewing distance
  1254. "_minlight" minimum lighting on a surf. overrides _mingridlight and _minvertexlight
  1255. Game Options
  1256. "fog" shader name of the global fog texture - must include the full path, such as "textures/rj/fog1"
  1257. "ls_Xr" override lightstyle X with this pattern for Red.
  1258. "ls_Xg" green (valid patterns are "a-z")
  1259. "ls_Xb" blue (a is OFF, z is ON)
  1260. "breath" Whether the entity's have breath puffs or not (0 = No, 1 = All, 2 = Just cold breath, 3 = Just under water bubbles ).
  1261. "clearstats" default 1, if 0 loading this map will not clear the stats for player
  1262. "tier_storyinfo" sets 'tier_storyinfo' cvar
  1263. */
  1264. void SP_worldspawn( void ) {
  1265. char *s;
  1266. int i;
  1267. g_entities[ENTITYNUM_WORLD].max_health = 0;
  1268. for ( i = 0 ; i < numSpawnVars ; i++ )
  1269. {
  1270. if ( Q_stricmp( "spawnscript", spawnVars[i][0] ) == 0 )
  1271. {//ONly let them set spawnscript, we don't want them setting an angle or something on the world.
  1272. G_ParseField( spawnVars[i][0], spawnVars[i][1], &g_entities[ENTITYNUM_WORLD] );
  1273. }
  1274. if ( Q_stricmp( "region", spawnVars[i][0] ) == 0 )
  1275. {
  1276. g_entities[ENTITYNUM_WORLD].s.radius = atoi(spawnVars[i][1]);
  1277. }
  1278. if ( Q_stricmp( "distancecull", spawnVars[i][0] ) == 0 )
  1279. {
  1280. g_entities[ENTITYNUM_WORLD].max_health = (int)((float)(atoi(spawnVars[i][1])) * 0.7f);
  1281. }
  1282. }
  1283. G_SpawnString( "classname", "", &s );
  1284. if ( Q_stricmp( s, "worldspawn" ) ) {
  1285. G_Error( "SP_worldspawn: The first entity isn't 'worldspawn'" );
  1286. }
  1287. // make some data visible to connecting client
  1288. G_SpawnString( "music", "", &s );
  1289. gi.SetConfigstring( CS_MUSIC, s );
  1290. G_SpawnString( "message", "", &s );
  1291. gi.SetConfigstring( CS_MESSAGE, s ); // map specific message
  1292. G_SpawnString( "gravity", "800", &s );
  1293. extern SavedGameJustLoaded_e g_eSavedGameJustLoaded;
  1294. if (g_eSavedGameJustLoaded != eFULL)
  1295. {
  1296. gi.cvar_set( "g_gravity", s );
  1297. }
  1298. G_SpawnString( "soundSet", "default", &s );
  1299. gi.SetConfigstring( CS_AMBIENT_SET, s );
  1300. //Lightstyles
  1301. gi.SetConfigstring(CS_LIGHT_STYLES+(LS_STYLES_START*3)+0, defaultStyles[0][0]);
  1302. gi.SetConfigstring(CS_LIGHT_STYLES+(LS_STYLES_START*3)+1, defaultStyles[0][1]);
  1303. gi.SetConfigstring(CS_LIGHT_STYLES+(LS_STYLES_START*3)+2, defaultStyles[0][2]);
  1304. for(i=1;i<LS_NUM_STYLES;i++)
  1305. {
  1306. char temp[32];
  1307. int lengthRed, lengthBlue, lengthGreen;
  1308. Com_sprintf(temp, sizeof(temp), "ls_%dr", i);
  1309. G_SpawnString( temp, defaultStyles[i][0], &s );
  1310. lengthRed = strlen(s);
  1311. gi.SetConfigstring(CS_LIGHT_STYLES+((i+LS_STYLES_START)*3)+0, s);
  1312. Com_sprintf(temp, sizeof(temp), "ls_%dg", i);
  1313. G_SpawnString(temp, defaultStyles[i][1], &s);
  1314. lengthGreen = strlen(s);
  1315. gi.SetConfigstring(CS_LIGHT_STYLES+((i+LS_STYLES_START)*3)+1, s);
  1316. Com_sprintf(temp, sizeof(temp), "ls_%db", i);
  1317. G_SpawnString(temp, defaultStyles[i][2], &s);
  1318. lengthBlue = strlen(s);
  1319. gi.SetConfigstring(CS_LIGHT_STYLES+((i+LS_STYLES_START)*3)+2, s);
  1320. if (lengthRed != lengthGreen || lengthGreen != lengthBlue)
  1321. {
  1322. Com_Error(ERR_DROP, "Style %d has inconsistent lengths: R %d, G %d, B %d",
  1323. i, lengthRed, lengthGreen, lengthBlue);
  1324. }
  1325. }
  1326. G_SpawnString( "breath", "0", &s );
  1327. gi.cvar_set( "cg_drawBreath", s );
  1328. G_SpawnString( "clearstats", "1", &s );
  1329. gi.cvar_set( "g_clearstats", s );
  1330. if (G_SpawnString( "tier_storyinfo", "", &s ))
  1331. {
  1332. gi.cvar_set( "tier_storyinfo", s );
  1333. }
  1334. g_entities[ENTITYNUM_WORLD].s.number = ENTITYNUM_WORLD;
  1335. g_entities[ENTITYNUM_WORLD].classname = "worldspawn";
  1336. }
  1337. /*
  1338. -------------------------
  1339. G_ParsePrecaches
  1340. -------------------------
  1341. */
  1342. void G_ParsePrecaches( void )
  1343. {
  1344. gentity_t *ent = NULL;
  1345. //Clear any old lists
  1346. if(!as_preCacheMap) {
  1347. as_preCacheMap = new namePrecache_m;
  1348. }
  1349. as_preCacheMap->clear();
  1350. for ( int i = 0; i < globals.num_entities; i++ )
  1351. {
  1352. ent = &g_entities[i];
  1353. if VALIDSTRING( ent->soundSet )
  1354. {
  1355. (*as_preCacheMap)[ (char *) ent->soundSet ] = 1;
  1356. }
  1357. }
  1358. }
  1359. void G_ASPreCacheFree(void)
  1360. {
  1361. if(as_preCacheMap) {
  1362. delete as_preCacheMap;
  1363. as_preCacheMap = NULL;
  1364. }
  1365. }
  1366. /*
  1367. ==============
  1368. G_SpawnEntitiesFromString
  1369. Parses textual entity definitions out of an entstring and spawns gentities.
  1370. ==============
  1371. */
  1372. extern int num_waypoints;
  1373. extern void RG_RouteGen(void);
  1374. extern qboolean NPCsPrecached;
  1375. qboolean SP_bsp_worldspawn ( void )
  1376. {
  1377. return qtrue;
  1378. }
  1379. void G_SubBSPSpawnEntitiesFromString(const char *entityString, vec3_t posOffset, vec3_t angOffset)
  1380. {
  1381. const char *entities;
  1382. entities = entityString;
  1383. // allow calls to G_Spawn*()
  1384. spawning = qtrue;
  1385. NPCsPrecached = qfalse;
  1386. numSpawnVars = 0;
  1387. // the worldspawn is not an actual entity, but it still
  1388. // has a "spawn" function to perform any global setup
  1389. // needed by a level (setting configstrings or cvars, etc)
  1390. if ( !G_ParseSpawnVars( &entities ) ) {
  1391. G_Error( "SpawnEntities: no entities" );
  1392. }
  1393. // Skip this guy if its worldspawn fails
  1394. if ( !SP_bsp_worldspawn() )
  1395. {
  1396. return;
  1397. }
  1398. // parse ents
  1399. while( G_ParseSpawnVars(&entities) )
  1400. {
  1401. G_SpawnSubBSPGEntityFromSpawnVars(posOffset, angOffset);
  1402. }
  1403. }
  1404. void G_SpawnEntitiesFromString( const char *entityString ) {
  1405. const char *entities;
  1406. entities = entityString;
  1407. // allow calls to G_Spawn*()
  1408. spawning = qtrue;
  1409. NPCsPrecached = qfalse;
  1410. numSpawnVars = 0;
  1411. // the worldspawn is not an actual entity, but it still
  1412. // has a "spawn" function to perform any global setup
  1413. // needed by a level (setting configstrings or cvars, etc)
  1414. if ( !G_ParseSpawnVars( &entities ) ) {
  1415. G_Error( "SpawnEntities: no entities" );
  1416. }
  1417. SP_worldspawn();
  1418. // parse ents
  1419. while( G_ParseSpawnVars( &entities ) )
  1420. {
  1421. G_SpawnGEntityFromSpawnVars();
  1422. }
  1423. //Search the entities for precache information
  1424. G_ParsePrecaches();
  1425. if( g_entities[ENTITYNUM_WORLD].behaviorSet[BSET_SPAWN] && g_entities[ENTITYNUM_WORLD].behaviorSet[BSET_SPAWN][0] )
  1426. {//World has a spawn script, but we don't want the world in ICARUS and running scripts,
  1427. //so make a scriptrunner and start it going.
  1428. gentity_t *script_runner = G_Spawn();
  1429. if ( script_runner )
  1430. {
  1431. script_runner->behaviorSet[BSET_USE] = g_entities[ENTITYNUM_WORLD].behaviorSet[BSET_SPAWN];
  1432. script_runner->count = 1;
  1433. script_runner->e_ThinkFunc = thinkF_scriptrunner_run;
  1434. script_runner->nextthink = level.time + 100;
  1435. if ( Quake3Game()->ValidEntity( script_runner ) )
  1436. {
  1437. Quake3Game()->InitEntity( script_runner ); //ICARUS_InitEnt( script_runner );
  1438. }
  1439. }
  1440. }
  1441. //gi.Printf(S_COLOR_YELLOW"Total waypoints: %d\n", num_waypoints);
  1442. //Automatically run routegen
  1443. //RG_RouteGen();
  1444. spawning = qfalse; // any future calls to G_Spawn*() will be errors
  1445. if ( g_delayedShutdown->integer && delayedShutDown )
  1446. {
  1447. assert(0);
  1448. G_Error( "Errors loading map, check the console for them." );
  1449. }
  1450. }