home *** CD-ROM | disk | FTP | other *** search
/ Qu-ake / Qu-ake.iso / qu_ke / patches / 014 / DMCAM.QC < prev    next >
Encoding:
Text File  |  1996-09-17  |  7.1 KB  |  225 lines

  1. //DocWilco's DeathMatch Camera patch version 1.1
  2.  
  3. //Some of this code is not used but I left it here because I sometimes use
  4. //it when I test stuff, and for some people maybe to learn from.
  5.  
  6.  
  7. //FindNextIntermission looks for the next Intermission view in the level
  8. //It is a modified FindIntermission from client.qc
  9.  
  10. entity() FindNextIntermission =
  11. {
  12.     local    entity spot;
  13.  
  14.         spot = find (CurrentCamPos, classname, "info_intermission");
  15.         if (!spot)
  16.               spot = find (spot, classname, "info_intermission");
  17.         return spot;
  18. };
  19.  
  20. // Not used. But if used instead of CheckCams in InitCamClient
  21. // the camera will cycle through all the views in the level.
  22.  
  23. void() NextCamPosition =
  24. {
  25.         local entity spot;
  26.  
  27.         spot = FindNextIntermission();
  28.         CurrentCamPos = spot;
  29.  
  30.         setorigin(self, spot.origin);
  31.         self.angles = self.v_angle = spot.mangle;
  32.         msg_entity = self;
  33.         if (self.flags & FL_CLIENT)               //Is it really a client?  
  34.            WriteByte (MSG_ONE, SVC_INTERMISSION); //This is a hack to update the screen.
  35.         self.think = NextCamPosition;
  36.         self.nextthink = time + 3;
  37. };
  38.  
  39. // inview returns TRUE if the angle between the line from the camera to the
  40. // target makes an angle of 60 degrees or less with the camera's direction
  41. // of view.
  42. // Heavily modified infront from ai.qc
  43. // I could not have done this without the stuff I learned at maths years ago
  44. // If you don't understand this, looking up normalize in builtin.c might
  45. // help. Normalize makes the vector exactly 1 unit long. And read some stuff
  46. // about vectors.
  47.  
  48. float(entity cam, entity targ) inview =
  49. {
  50.         local vector    vec1;
  51.         local vector    vec2;
  52.     local float        dot;
  53.     
  54.         makevectors (cam.mangle);
  55.         vec1 = normalize (targ.origin - cam.origin);
  56.         vec2 = normalize (v_forward);
  57.         dot = vlen(vec1 - vec2);
  58. //        bprint(vtos(vec1));
  59. //        bprint("\n");
  60. //        bprint(vtos(vec2));
  61. //        bprint("\n");
  62. //        bprint(ftos(dot));
  63. //        bprint(" ");
  64.  
  65.         if ((dot <= 1) && (dot >= -1))
  66.     {
  67. //                bprint ("In view ");
  68.         return TRUE;
  69.     }
  70.     return FALSE;
  71. };
  72.  
  73. // VisibleToCam
  74. // Checks whether there are any walls between the camera and the player.
  75. // So even if the player is not in view, but is visible from the point where
  76. // the camera is, this function returns true.
  77. // Modified visible from ai.qc
  78.  
  79. float (entity cam, entity targ) VisibleToCam =
  80. {
  81.     local vector    spot1, spot2;
  82.     
  83.         spot1 = cam.origin;
  84.     spot2 = targ.origin + targ.view_ofs;
  85.     traceline (spot1, spot2, TRUE, self);    // see through other monsters
  86.     
  87.     if (trace_inopen && trace_inwater)
  88.         return FALSE;            // sight line crossed contents
  89.  
  90.     if (trace_fraction == 1)
  91.         return TRUE;
  92.     return FALSE;
  93. };
  94.  
  95.  
  96. // CheckView
  97. // Checks the given view for players, and returns the amount of players in view
  98.  
  99. float(entity cam) CheckView =
  100. {
  101.         local float NumOfPlayers;
  102.         local entity client;
  103.         local float DistToCam;
  104.  
  105.         NumOfPlayers = 0;
  106.         DistToCam = 0;
  107.         client = find (world, classname, "player");
  108.         while (client != world)
  109.     {
  110.                 if (inview(cam, client) && VisibleToCam(cam, client))
  111.                 {
  112.                    NumOfPlayers = NumOfPlayers + 1;
  113.                    DistToCam = DistToCam + vlen(client.origin - cam.origin);
  114.                 }
  115. //                bprint("Checked ");
  116. //                bprint(client.netname);
  117. //                bprint(" ");
  118. //                bprint(ftos(client.team));
  119. //                bprint("\n");
  120.                 client = find (client, classname, "player");
  121.     }
  122. //        bprint(ftos(NumOfPlayers));
  123. //        bprint(" ");
  124.         AvgDist = DistToCam / NumOfPlayers;
  125.         return NumOfPlayers;
  126. };
  127.  
  128. // CheckCams
  129. // Checks every intermission view for the amount of players in view. The view
  130. // with the most players in view and the lowest average distance to the players
  131. // in view is made the next view.
  132. // I am thinking of changing this the most.
  133.  
  134. void() CheckCams =
  135. {
  136.         local entity cam;
  137.         local entity bestcam;
  138.         local float highnum;
  139.         local float camnum;
  140.         local float lowdist;
  141.         local float foundany;
  142.  
  143.         bestcam = CurrentCamPos;     //If no view is found the current view is kept.
  144.         highnum = 0;
  145.         foundany = FALSE;
  146.         lowdist = 100000;
  147.         cam = find (world, classname, "info_intermission");
  148.         while (cam != world)
  149.         {
  150.                 camnum = CheckView(cam);
  151. //                bprint(ftos(camnum));
  152. //                bprint(" ");
  153. //                bprint(ftos(AvgDist));
  154. //                bprint(" ");
  155. //                bprint(ftos(highnum));
  156. //                bprint(" ");
  157.                 if ((highnum < camnum) && (camnum > 0))
  158.                         {
  159.                                 bestcam = cam;
  160.                                 highnum = camnum;
  161.                                 lowdist = AvgDist;
  162.                                 foundany = TRUE;
  163. //                                bprint("more ");
  164.                         }
  165.                 if ((camnum = highnum) && (camnum > 0) && (AvgDist <= lowdist))
  166.                         {
  167.                                 bestcam = cam;
  168.                                 lowdist = AvgDist;
  169.                                 foundany = TRUE;
  170.                         }
  171.                 cam = find (cam, classname, "info_intermission");
  172.         }
  173. //        bprint("\n");
  174. //        bprint(ftos(highnum));
  175. //        bprint(" players in view\n");
  176.         if (foundany == FALSE)
  177.                 {
  178.                         if (time >= nextviewtime)
  179.                                 {
  180.                                         bestcam = FindNextIntermission();
  181.                                         nextviewtime = time + 3;
  182.                                 }
  183. //                        bprint("Nothing in view\n");
  184.                 }
  185.         CurrentCamPos = bestcam;
  186.         setorigin(self, bestcam.origin);
  187.         self.angles = self.v_angle = bestcam.mangle;
  188.         msg_entity = self;
  189.         if (self.flags & FL_CLIENT)
  190.            WriteByte (MSG_ONE, SVC_INTERMISSION);
  191.         self.think = CheckCams;
  192.         self.nextthink = time + 0.5;
  193.  
  194. };
  195.  
  196. // InitCamClient
  197. // Turns the client from a player into the camera.
  198.  
  199. void() InitCamClient =
  200. {
  201.         local entity spot;
  202.  
  203.         bprint("Camera initialised\n");
  204.         self.classname = "CameraClient";
  205.         setmodel (self, string_null);
  206.         setsize (self, '0 0 0', '0 0 0');
  207.         self.view_ofs = '0 0 0';
  208.         self.movetype = MOVETYPE_NONE;
  209.         self.solid = SOLID_NOT;
  210.         self.takedamage = DAMAGE_NO;
  211.         nextviewtime = time;
  212.  
  213.         spot = FindIntermission() ;   //pick a random view to start from
  214.         CurrentCamPos = spot;
  215.  
  216.         setorigin(self, spot.origin);
  217.         self.angles = self.v_angle = spot.mangle;
  218.         msg_entity = self;
  219.         if (self.flags & FL_CLIENT)
  220.            WriteByte (MSG_ONE, SVC_INTERMISSION);
  221.         self.think = CheckCams;
  222.         self.nextthink = time + 3;
  223. };
  224.  
  225.