ending.qc 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417
  1. /* Copyright (C) 1996-2022 id Software LLC
  2. This program is free software; you can redistribute it and/or modify
  3. it under the terms of the GNU General Public License as published by
  4. the Free Software Foundation; either version 2 of the License, or
  5. (at your option) any later version.
  6. This program is distributed in the hope that it will be useful,
  7. but WITHOUT ANY WARRANTY; without even the implied warranty of
  8. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  9. GNU General Public License for more details.
  10. You should have received a copy of the GNU General Public License
  11. along with this program; if not, write to the Free Software
  12. Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  13. See file, 'COPYING', for details.
  14. */
  15. // ending.qc
  16. // code to handle big ending of Xpack.
  17. // ------------------------------------------------
  18. $frame axrun1 axrun2 axrun3 axrun4 axrun5 axrun6
  19. $frame rockrun1 rockrun2 rockrun3 rockrun4 rockrun5 rockrun6
  20. $frame stand1 stand2 stand3 stand4 stand5
  21. $frame axstnd1 axstnd2 axstnd3 axstnd4 axstnd5 axstnd6
  22. $frame axstnd7 axstnd8 axstnd9 axstnd10 axstnd11 axstnd12
  23. $frame axpain1 axpain2 axpain3 axpain4 axpain5 axpain6
  24. $frame pain1 pain2 pain3 pain4 pain5 pain6
  25. $frame axdeth1 axdeth2 axdeth3 axdeth4 axdeth5 axdeth6
  26. $frame axdeth7 axdeth8 axdeth9
  27. $frame deatha1 deatha2 deatha3 deatha4 deatha5 deatha6 deatha7 deatha8
  28. $frame deatha9 deatha10 deatha11
  29. $frame deathb1 deathb2 deathb3 deathb4 deathb5 deathb6 deathb7 deathb8
  30. $frame deathb9
  31. $frame deathc1 deathc2 deathc3 deathc4 deathc5 deathc6 deathc7 deathc8
  32. $frame deathc9 deathc10 deathc11 deathc12 deathc13 deathc14 deathc15
  33. $frame deathd1 deathd2 deathd3 deathd4 deathd5 deathd6 deathd7
  34. $frame deathd8 deathd9
  35. $frame deathe1 deathe2 deathe3 deathe4 deathe5 deathe6 deathe7
  36. $frame deathe8 deathe9
  37. $frame nailatt1 nailatt2
  38. $frame light1 light2
  39. $frame rockatt1 rockatt2 rockatt3 rockatt4 rockatt5 rockatt6
  40. $frame shotatt1 shotatt2 shotatt3 shotatt4 shotatt5 shotatt6
  41. $frame axatt1 axatt2 axatt3 axatt4 axatt5 axatt6
  42. $frame axattb1 axattb2 axattb3 axattb4 axattb5 axattb6
  43. $frame axattc1 axattc2 axattc3 axattc4 axattc5 axattc6
  44. $frame axattd1 axattd2 axattd3 axattd4 axattd5 axattd6
  45. entity theActor;
  46. entity theMachine;
  47. float actorStage;
  48. float STAGE_START = 0;
  49. float STAGE_TO_POINT1 = 1;
  50. float STAGE_AT_POINT1 = 2;
  51. float STAGE_TO_POINT2 = 3;
  52. float STAGE_AT_POINT2 = 4;
  53. float STAGE_FIRING = 5;
  54. void(entity thePlayer) spawn_actor;
  55. void() actor_control;
  56. void(entity playerEnt) move_camera;
  57. void() time_crash;
  58. void() ending_remove_stuff;
  59. void() ending_for_coop =
  60. {
  61. intermission_exittime = time + 3;
  62. intermission_running = 1;
  63. self.model = "";
  64. self.yaw_speed = 20;
  65. self.view_ofs = '0 0 0';
  66. self.takedamage = DAMAGE_NO;
  67. self.solid = SOLID_NOT;
  68. self.movetype = MOVETYPE_NONE;
  69. self.modelindex = 0;
  70. setorigin (self, self.origin + '0 0 48');
  71. WriteByte (MSG_ALL, SVC_FINALE);
  72. WriteString (MSG_ALL, "$qc_finale_coop");
  73. ending_remove_stuff();
  74. theMachine.think = time_crash;
  75. theMachine.nextthink = time + 0.1;
  76. };
  77. // ------------------------------------------------
  78. // Camera and control functions
  79. // ------------------------------------------------
  80. void() xpackEnding =
  81. {
  82. local entity cameraview;
  83. if (coop)
  84. {
  85. ending_for_coop();
  86. return;
  87. }
  88. intermission_exittime = time + 10000000; // never allow exit
  89. intermission_running = 1;
  90. WriteByte (MSG_ALL, SVC_CUTSCENE);
  91. WriteString (MSG_ALL, "");
  92. cameraview = find ( world, targetname, "cameraview");
  93. if (cameraview == world)
  94. {
  95. ending_for_coop();
  96. return;
  97. }
  98. self.solid = SOLID_NOT;
  99. self.movetype = MOVETYPE_NONE;
  100. spawn_actor(self);
  101. move_camera(self);
  102. };
  103. void() track_camera =
  104. {
  105. local vector cameraAngle;
  106. cameraAngle = theActor.origin - self.origin;
  107. cameraAngle_z = 0 - cameraAngle_z;
  108. self.angles = vectoangles ( cameraAngle );
  109. self.v_angle = self.angles;
  110. self.think = track_camera;
  111. self.nextthink = time + 0.1;
  112. };
  113. void(entity playerEnt) move_camera =
  114. {
  115. local entity cameraPoint;
  116. local vector cameraAngle;
  117. cameraPoint = find ( world, targetname, "cameraview");
  118. if ( cameraPoint == world )
  119. objerror ("Could not find camerapoint!");
  120. self.model = "";
  121. self.yaw_speed = 20;
  122. self.view_ofs = '0 0 0';
  123. self.takedamage = DAMAGE_NO;
  124. self.solid = SOLID_NOT;
  125. self.movetype = MOVETYPE_NONE;
  126. self.modelindex = 0;
  127. setorigin (self, cameraPoint.origin);
  128. cameraAngle = theActor.origin - self.origin;
  129. self.angles = vectoangles ( cameraAngle );
  130. self.v_angle = self.angles;
  131. self.think = track_camera;
  132. self.nextthink = time + 0.05;
  133. };
  134. void() ending_remove_stuff =
  135. {
  136. local entity curEnt;
  137. local entity removeEnt;
  138. curEnt = find ( world, classname, "ltrail_start");
  139. while(curEnt)
  140. {
  141. remove(curEnt);
  142. curEnt = find ( world, classname, "ltrail_start");
  143. }
  144. curEnt = find ( world, classname, "item_time_core");
  145. WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
  146. WriteByte (MSG_BROADCAST, TE_EXPLOSION2);
  147. WriteCoord (MSG_BROADCAST, curEnt.origin_x);
  148. WriteCoord (MSG_BROADCAST, curEnt.origin_y);
  149. WriteCoord (MSG_BROADCAST, curEnt.origin_z);
  150. WriteByte (MSG_BROADCAST, 230);
  151. WriteByte (MSG_BROADCAST, 5);
  152. curEnt.think = SUB_Remove;
  153. curEnt.nextthink = time + 0.1;
  154. };
  155. // ------------------------------------------------
  156. // actor code
  157. // ------------------------------------------------
  158. void() actor_run =
  159. {
  160. local vector dist;
  161. local float ang;
  162. local entity pointOne;
  163. if ( pointcontents (self.origin) == CONTENT_LAVA )
  164. {
  165. pointOne = find ( world, targetname, "point1" );
  166. if (pointOne != world)
  167. setorigin ( self, pointOne.origin );
  168. }
  169. if ( self.goalentity.targetname == "endpoint1")
  170. {
  171. actorStage = STAGE_AT_POINT1;
  172. self.think = actor_control;
  173. self.nextthink = time + 0.1;
  174. return;
  175. }
  176. if ( self.goalentity.targetname == "endpoint2")
  177. {
  178. actorStage = STAGE_AT_POINT2;
  179. self.think = actor_control;
  180. self.nextthink = time + 0.1;
  181. return;
  182. }
  183. self.frame = self.frame + 1;
  184. if (self.frame > 11)
  185. self.frame = 6;
  186. dist = self.goalentity.origin - self.origin;
  187. // self.ideal_yaw = vectoyaw ( dist );
  188. // ChangeYaw();
  189. movetogoal ( 15 );
  190. self.think = actor_run;
  191. self.nextthink = time + 0.1;
  192. };
  193. void() finale_transition =
  194. {
  195. if (!coop) {
  196. localcmd("menu_credits\n");
  197. localcmd("disconnect\n");
  198. } else {
  199. changelevel("start");
  200. }
  201. }
  202. void() finale_check =
  203. {
  204. if (finaleFinished()) {
  205. self.nextthink = time + 5;
  206. self.think = finale_transition;
  207. } else {
  208. self.nextthink = time + 0.1;
  209. }
  210. }
  211. void() actor_fire1 =[$rockatt1, actor_fire2 ]
  212. {
  213. self.goalentity = theMachine;
  214. theMachine.th_pain = time_crash;
  215. theMachine.th_die = time_crash;
  216. theMachine.health = 1;
  217. self.angles = vectoangles ( self.goalentity.origin - self.origin );
  218. self.v_angle = self.angles;
  219. self.v_angle_x = 0 - self.angles_x;
  220. self.effects = EF_MUZZLEFLASH;
  221. W_FireRocket();
  222. // start the end text
  223. WriteByte (MSG_ALL, SVC_FINALE);
  224. WriteString (MSG_ALL, "$qc_finale_rogue_end");
  225. if (campaign && world.model == "maps/r2m8.bsp")
  226. {
  227. WriteByte (MSG_ALL, SVC_ACHIEVEMENT);
  228. WriteString(MSG_ALL, "ACH_COMPLETE_R2M8");
  229. if (skill == 3)
  230. {
  231. WriteByte (MSG_ALL, SVC_ACHIEVEMENT);
  232. WriteString(MSG_ALL, "ACH_COMPLETE_R2M8_NIGHTMARE");
  233. }
  234. }
  235. // instead of sitting here forever, run the quake ex credits and send the user back to start
  236. local entity timer = spawn();
  237. timer.nextthink = time + 1;
  238. timer.think = finale_check;
  239. };
  240. void() actor_fire2 =[$rockatt2, actor_fire3 ]
  241. {self.v_angle_x = 0; self.angles_x = 0; self.nextthink=time+0.15;};
  242. void() actor_fire3 =[$rockatt3, actor_fire4 ] {self.nextthink=time+0.15;};
  243. void() actor_fire4 =[$rockatt4, actor_fire5 ] {self.nextthink=time+0.15;};
  244. void() actor_fire5 =[$rockatt5, actor_fire6 ]
  245. {
  246. self.nextthink=time+0.15;
  247. ending_remove_stuff();
  248. if (theMachine.health > 0)
  249. {
  250. theMachine.think = time_crash;
  251. theMachine.nextthink = time + 0.1;
  252. }
  253. };
  254. void() actor_fire6 =[$rockatt6, actor_fire7 ]
  255. { self.effects=0;self.nextthink=time+0.15;};
  256. void() actor_fire7 =[$stand1, actor_fire8 ] {self.nextthink=time+0.15;};
  257. void() actor_fire8 =[$stand2, actor_fire9 ] {self.nextthink=time+0.15;};
  258. void() actor_fire9 =[$stand3, actor_fire10 ] {self.nextthink=time+0.15;};
  259. void() actor_fire10 =[$stand4, actor_fire11 ] {self.nextthink=time+0.15;};
  260. void() actor_fire11 =[$stand5, actor_fire12 ] {self.nextthink=time+0.15;};
  261. void() actor_fire12 =[$stand1, actor_fire13 ] {self.nextthink=time+0.15;};
  262. void() actor_fire13 =[$stand2, actor_fire14 ] {self.nextthink=time+0.15;};
  263. void() actor_fire14 =[$stand3, actor_fire15 ] {self.nextthink=time+0.15;};
  264. void() actor_fire15 =[$stand4, actor_fire16 ] {self.nextthink=time+0.15;};
  265. void() actor_fire16 =[$stand5, actor_fire17 ] {self.nextthink=time+0.15;};
  266. void() actor_fire17 =[$stand1, actor_fire18 ] {self.nextthink=time+0.15;};
  267. void() actor_fire18 =[$stand2, actor_fire19 ] {self.nextthink=time+0.15;};
  268. void() actor_fire19 =[$stand3, actor_fire20 ] {self.nextthink=time+0.15;};
  269. void() actor_fire20 =[$stand4, actor_fire21 ] {self.nextthink=time+0.15;};
  270. void() actor_fire21 =[$stand5, actor_control ]
  271. {
  272. self.nextthink=time+0.15;
  273. actorStage = STAGE_TO_POINT2;
  274. };
  275. void() actor_teleport =
  276. {
  277. spawn_tfog(self.origin);
  278. self.model = string_null;
  279. self.think = SUB_Null;
  280. self.nextthink = time + 999999;
  281. };
  282. void() actor_control =
  283. {
  284. local entity timepod;
  285. if (actorStage == STAGE_START)
  286. {
  287. self.target = "point1";
  288. self.movetarget = find (world, targetname, self.target);
  289. self.goalentity = self.movetarget;
  290. if ( self.goalentity == world )
  291. objerror ("End Sequence point1 placing screwed up!");
  292. self.frame = 6;
  293. self.think = actor_run;
  294. self.nextthink = time + 0.1;
  295. actorStage = STAGE_TO_POINT1;
  296. }
  297. else if (actorStage == STAGE_AT_POINT1)
  298. {
  299. self.target = "machine";
  300. self.movetarget = find (world, targetname, self.target);
  301. self.goalentity = self.movetarget;
  302. if ( self.goalentity == world )
  303. objerror ("End Sequence machine placing screwed up!");
  304. actorStage = STAGE_FIRING;
  305. self.think = actor_fire1;
  306. self.nextthink = time + 0.1;
  307. }
  308. else if (actorStage == STAGE_AT_POINT2)
  309. {
  310. self.frame = $stand1;
  311. self.think = actor_teleport;
  312. self.nextthink = time + 2;
  313. }
  314. else if (actorStage == STAGE_TO_POINT2)
  315. {
  316. self.target = "timepod";
  317. SUB_UseTargets();
  318. self.target = "point2";
  319. self.movetarget = find (world, targetname, self.target);
  320. self.goalentity = self.movetarget;
  321. if ( self.goalentity == world )
  322. objerror ("End Sequence point2 placing screwed up!");
  323. self.frame = 6;
  324. self.think = actor_run;
  325. self.nextthink = time + 0.1;
  326. }
  327. };
  328. // ==============
  329. // player actor spawn function
  330. // ==============
  331. void(entity thePlayer) spawn_actor =
  332. {
  333. local entity pointOne;
  334. theActor = spawn();
  335. theActor.owner = self;
  336. theActor.classname = "actor";
  337. theActor.health = 100;
  338. theActor.solid = SOLID_SLIDEBOX;
  339. theActor.movetype = MOVETYPE_STEP;
  340. theActor.frame = self.frame;
  341. setmodel ( theActor, "progs/player.mdl");
  342. setorigin ( theActor, self.origin);
  343. setsize (theActor, VEC_HULL_MIN, VEC_HULL_MAX);
  344. theActor.view_ofs = '0 0 22';
  345. theActor.angles = self.angles;
  346. theActor.ideal_yaw = theActor.angles * '0 1 0';
  347. if (!theActor.yaw_speed)
  348. theActor.yaw_speed = 20;
  349. theActor.view_ofs = '0 0 25';
  350. theActor.flags = theActor.flags | FL_MONSTER;
  351. actorStage == STAGE_START;
  352. if ( pointcontents (theActor.origin) == CONTENT_LAVA )
  353. {
  354. pointOne = find ( world, targetname, "point1" );
  355. if (pointOne != world)
  356. setorigin ( theActor, pointOne.origin );
  357. }
  358. theActor.think = actor_control;
  359. theActor.nextthink = time + 0.1;
  360. };