home *** CD-ROM | disk | FTP | other *** search
/ Superpower (Alt) / SUPERPOWER.iso / q / patch / mbq090 / _observe.qc < prev    next >
Encoding:
Text File  |  1996-08-29  |  13.6 KB  |  399 lines

  1. /*
  2. **
  3. ** _observe.qc (Observer Code, 1.6)
  4. **
  5. ** Copyright (C) 1996 Johannes Plass
  6. ** 
  7. ** This program is free software; you can redistribute it and/or modify
  8. ** it under the terms of the GNU General Public License as published by
  9. ** the Free Software Foundation; either version 2 of the License, or
  10. ** (at your option) any later version.
  11. ** 
  12. ** This program is distributed in the hope that it will be useful,
  13. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15. ** GNU General Public License for more details.
  16. **
  17. ** You should have received a copy of the GNU General Public License
  18. ** along with this program; if not, write to the Free Software
  19. ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20. ** 
  21. ** Author:   Johannes Plass (plass@dipmza.physik.uni-mainz.de)
  22. **
  23. */
  24.  
  25. void(entity player) ObserverSetPlayerPos;
  26. void(entity player,entity door) ObserverTeleportThroughDoor;
  27. void(entity player,entity tele) ObserverTeleportThroughTeleporter;
  28.  
  29. void(entity player) ObserverInfo =
  30. {
  31.    if (!USE_MODULE_OBSERVER) return;
  32.    sprint(player,"# Observer: Allows you to peep.\n");
  33.    sprint(player,"  Type 'help-observer' for help.\n");
  34. };
  35.  
  36. void(entity player) ObserverInit =
  37. {
  38.    if (!USE_MODULE_OBSERVER) return;
  39.    stuffcmd(player,"alias help-observer \"impulse 205\";\n");
  40.    stuffcmd(player,"alias observer-noclip \"impulse 206\";\n");
  41. };
  42.  
  43. void(entity player) ObserverHelp =
  44. {
  45.    if (!USE_MODULE_OBSERVER) return;
  46.  
  47. //                123456789#123456789#123456789#12345678
  48.    sprint(player,"# Observer: Allows to watch the\n");
  49.    sprint(player,"  ongoing madness.\n");
  50.    sprint(player,"  As observer you can:\n");
  51.    sprint(player,"    - fly around.\n");
  52.    sprint(player,"    - move to another watch-spot by \n");
  53.    sprint(player,"      pressing the fire-button. \n");
  54.    sprint(player,"    - join the game as regular player\n");
  55.    sprint(player,"      by pressing the jump-button. \n");
  56.    sprint(player,"  Use the command 'observer-noclip'\n");
  57.    sprint(player,"  to turn clipping on or off.\n");
  58.    sprint(player,"  Press the fire-button to become an\n");
  59.    sprint(player,"  observer when you are dead.\n");
  60. };
  61.  
  62. void () ObserverThink =
  63. {
  64.    //dprint("ObserverThink: executing\n");//#jp#(debug)
  65.  
  66.    if (!USE_MODULE_OBSERVER) return;
  67.  
  68.    self.weaponmodel = "";
  69.    self.weaponframe = 0;
  70.    //#jp# Hack to provide a decent flying velocity.
  71.    //#jp# Damn it, what a mess this quakec is.
  72.    self.flags = self.flags | FL_ONGROUND;
  73.  
  74.    { 
  75.       local float invcos,nv,nvp,nvpmax,nvs,nsp,sp,svz;
  76.       local vector f,vp,vs;
  77.  
  78.       svz = self.velocity_z * 0.75;
  79.       self.velocity_z = 0;
  80.  
  81.       // v_forward is already normalized
  82.       f_x = v_forward_x; 
  83.       f_y = v_forward_y; 
  84.       f_z = 0;
  85.       invcos = vlen(f); if (invcos) invcos= 1/invcos; else invcos=0;
  86.       f = f*invcos; // normalize f
  87.  
  88.       sp = f * self.velocity;
  89.       vp = sp*f;
  90.       nvp = vlen(vp); if (sp<0) nvp = nvp*(-1);
  91.       vs = self.velocity - vp;
  92.  
  93.       vp = v_forward * (nvp * invcos);
  94.       vp_z = vp_z + svz;
  95.       nvp = vlen(vp);
  96.       nvpmax = (320 - 100*(v_forward * '0 0 1'));
  97.       if (nvp > nvpmax) { vp = vp * (nvpmax/nvp); }
  98.  
  99.       self.velocity = vp + vs;
  100.    }
  101.  
  102.    {
  103.       local entity e;
  104.       local float cont;
  105.       e = findradius(self.origin,75);
  106.       if (e) { cont = TRUE;  }
  107.       else   { cont = FALSE; }
  108.       while (cont) {
  109.          // dprint(e.classname); dprint("\n");
  110.          if (e.classname == "door") {
  111.             ObserverTeleportThroughDoor(self,e);
  112.             cont = FALSE;
  113.          }
  114.          if (e.classname == "trigger_teleport") {
  115.             ObserverTeleportThroughTeleporter(self,e);
  116.             cont = FALSE;
  117.          }
  118.          e = e.chain;
  119.          if (!e) { cont = FALSE; }
  120.       }
  121.    }
  122.  
  123.    if (self.observer_status & OBSERVER_BECOME_OBSERVER) {
  124.       ObserverBecomeObserver(self);
  125.       return;
  126.    }
  127.  
  128.    if (self.observer_status & OBSERVER_NEXTVIEW) {
  129.       self.observer_pos_num = self.observer_pos_num + 1;
  130.       ObserverSetPlayerPos(self);
  131.       self.observer_status = self.observer_status - OBSERVER_NEXTVIEW;
  132.       return;
  133.    }
  134.  
  135.    if (self.observer_status & OBSERVER_TOGGLE_NOCLIP) {
  136.       if (self.movetype == MOVETYPE_FLY) {
  137.          self.movetype = MOVETYPE_NOCLIP;
  138.          sprint(self,"noclip on\n");
  139.       } else {
  140.          self.movetype = MOVETYPE_FLY;
  141.          sprint(self,"noclip off\n");
  142.       }
  143.       self.observer_status = self.observer_status - OBSERVER_TOGGLE_NOCLIP;
  144.    }
  145.  
  146.    if (self.button0) {
  147.       self.observer_status = OBSERVER_BUTTON0;
  148.       return;
  149.    }
  150.    else if (self.button1) {
  151.       self.observer_status = 0;
  152.       return;
  153.    }
  154.    else if (self.button2) {
  155.       self.observer_status = OBSERVER_BUTTON2;
  156.       return;
  157.    }
  158.  
  159.    if (self.observer_status & OBSERVER_BUTTON0) {
  160.       self.observer_status = OBSERVER_NEXTVIEW;
  161.       return;
  162.    }
  163.  
  164.    if (self.observer_status & OBSERVER_BUTTON2) {
  165.       self.observer_status  = OBSERVER_RESPAWN;
  166.       return;
  167.    }
  168.  
  169.    if (self.observer_status & OBSERVER_RESPAWN) {
  170.       respawn();
  171.       // remove flag must be set after respawn()
  172.       PlayerFlagRemoveFlag(self,PLAYER_IS_OBSERVER);
  173.       return;
  174.    }
  175. };
  176.  
  177. float() ObserverDeathThink = 
  178. {
  179.    if (!USE_MODULE_OBSERVER) return(0);
  180.  
  181.    if (self.button0) {
  182.       self.observer_status = OBSERVER_BUTTON0;
  183.    }
  184.    else if (self.button1) {
  185.       self.observer_status = 0;
  186.    }
  187.    else if (self.button2) {
  188.       self.observer_status = OBSERVER_BUTTON2;
  189.    }
  190.    else if (self.observer_status & (OBSERVER_BUTTON0 | OBSERVER_BUTTON2)) {
  191.       if (self.observer_status & OBSERVER_BUTTON0) self.observer_status = OBSERVER_BECOME_OBSERVER;
  192.       else self.observer_status = 0;
  193.       respawn();
  194.    }
  195.    return(1);
  196. };
  197.  
  198. void(entity player) ObserverBecomeObserver =
  199. {
  200.    //dprint("ObserverBecomeObserver: executing\n");//#jp#(debug)
  201.  
  202.    player.armorvalue       = 0;
  203.    player.items            = 0;
  204.    player.health           = 999;
  205.    player.ammo_shells      = 0;
  206.    player.ammo_nails       = 0;
  207.    player.ammo_rockets     = 0;
  208.    player.ammo_cells       = 0;
  209.    player.weapon           = 0;
  210.    player.currentammo      = 1;
  211.    player.takedamage       = DAMAGE_NO;
  212.    player.solid            = SOLID_NOT;
  213.    player.movetype         = MOVETYPE_FLY;
  214.    player.deadflag         = DEAD_NO;
  215.  
  216.    setmodel (player, string_null);
  217.  
  218.    player.weaponmodel      = "";
  219.    player.weaponframe      = 0;
  220.  
  221.    player.observer_pos_num = 0;
  222.    player.observer_status  = 0;
  223.    player.observer_pos_num = 1 + random() * 4;
  224.    ObserverSetPlayerPos(player);
  225. };
  226.  
  227.  
  228. entity(entity player) ObserverFindPos =
  229. {
  230.    local entity spot;
  231.    local float pos_num_startsearch;
  232.  
  233.    //dprint("ObserverFindPos: executing\n");
  234.    if      (player.observer_pos_num <= 0)  player.observer_pos_num = 1;
  235.    else if (player.observer_pos_num >= 21) player.observer_pos_num = 1;
  236.    pos_num_startsearch = player.observer_pos_num;
  237.  
  238.    if (player.observer_pos_num <= 5) {
  239.                                                      spot = find (world, classname, "info_intermission");
  240.       if (player.observer_pos_num >= 2 && !(!spot))  spot = find (spot,  classname, "info_intermission");
  241.       if (player.observer_pos_num >= 3 && !(!spot))  spot = find (spot,  classname, "info_intermission");
  242.       if (player.observer_pos_num >= 4 && !(!spot))  spot = find (spot,  classname, "info_intermission");
  243.       if (!spot) player.observer_pos_num = 5;
  244.    }
  245.    if (player.observer_pos_num >= 5) {
  246.                                                      spot = find (world, classname, "info_player_deathmatch");
  247.       if (player.observer_pos_num >=  6 && !(!spot)) spot = find (spot,  classname, "info_player_deathmatch");
  248.       if (player.observer_pos_num >=  7 && !(!spot)) spot = find (spot,  classname, "info_player_deathmatch");
  249.       if (player.observer_pos_num >=  8 && !(!spot)) spot = find (spot,  classname, "info_player_deathmatch");
  250.       if (player.observer_pos_num >=  9 && !(!spot)) spot = find (spot,  classname, "info_player_deathmatch");
  251.       if (player.observer_pos_num >= 10 && !(!spot)) spot = find (spot,  classname, "info_player_deathmatch");
  252.       if (player.observer_pos_num >= 11 && !(!spot)) spot = find (spot,  classname, "info_player_deathmatch");
  253.       if (player.observer_pos_num >= 12 && !(!spot)) spot = find (spot,  classname, "info_player_deathmatch");
  254.       if (player.observer_pos_num >= 13 && !(!spot)) spot = find (spot,  classname, "info_player_deathmatch");
  255.       if (player.observer_pos_num >= 14 && !(!spot)) spot = find (spot,  classname, "info_player_deathmatch");
  256.       if (player.observer_pos_num >= 15 && !(!spot)) spot = find (spot,  classname, "info_player_deathmatch");
  257.       if (player.observer_pos_num >= 16 && !(!spot)) spot = find (spot,  classname, "info_player_deathmatch");
  258.       if (player.observer_pos_num >= 17 && !(!spot)) spot = find (spot,  classname, "info_player_deathmatch");
  259.       if (player.observer_pos_num >= 18 && !(!spot)) spot = find (spot,  classname, "info_player_deathmatch");
  260.       if (player.observer_pos_num >= 19 && !(!spot)) spot = find (spot,  classname, "info_player_deathmatch");
  261.       if (player.observer_pos_num >= 20 && !(!spot)) spot = find (spot,  classname, "info_player_deathmatch");
  262.       if (!spot) player.observer_pos_num = 21;
  263.    }
  264.    if (player.observer_pos_num >= 21) {
  265.          spot = find (world, classname, "info_player_start");
  266.          player.observer_pos_num = 21;
  267.    }
  268.    if (!spot && pos_num_startsearch != 1) {
  269.       player.observer_pos_num = player.observer_pos_num + 1;
  270.       spot=ObserverFindPos(player);
  271.    }
  272.    if (!spot) error ("ObserverFindPos: could not find start pos");
  273.    return spot;
  274. };
  275.  
  276. void(entity player) ObserverSetPlayerPos =
  277. {
  278.    local entity pos;
  279.  
  280.    //dprint("ObserverSetPlayerPos: executing\n");//#jp#(debug)
  281.  
  282.    pos = ObserverFindPos(player);
  283.  
  284.    player.angles        = player.v_angle = pos.mangle;
  285.    player.fixangle      = TRUE;         // turn this way immediately
  286.    player.view_ofs      = '0 0 12'; // must be != '0 0 0'
  287.    player.velocity      = '0 0 0';
  288.  
  289.    makevectors (player.angles);
  290.    setsize (player, '-12  -12 -12', '12 12 12');
  291.    // setsize (player, VEC_HULL_MIN, VEC_HULL_MAX);
  292.    // player.view_ofs = '0 0 22';
  293.  
  294.    // avoid stuck observers for intermission spots 
  295.    if (player.observer_pos_num <=4) setorigin (player, pos.origin + '0 0 -60');
  296.    else                             setorigin (player, pos.origin);
  297. };
  298.  
  299. void(entity player) ObserverNoclip =
  300. {
  301.    if (!USE_MODULE_OBSERVER) return;
  302.  
  303.    player.observer_status = player.observer_status | OBSERVER_TOGGLE_NOCLIP;
  304. };
  305.  
  306. void(entity player,entity door) ObserverTeleportThroughDoor =
  307. {
  308.    local entity d,d_master;
  309.    local vector dmin,dmax;
  310.  
  311.    d_master = d = door.owner;
  312.    if (d_master) {
  313.       dmin = d_master.absmin;
  314.       dmax = d_master.absmax;
  315.    } else { 
  316.       dmin = dmax = '0 0 0'; 
  317.    }
  318.    if (dmin != dmax) {
  319.       // regular doors
  320.       if (d_master.state != STATE_BOTTOM) return;
  321.       do {
  322.          // dprint (vtos(d.absmin)); dprint (" "); dprint (vtos(d.absmax)); dprint ("\n");
  323.          if (d.absmin_x < dmin_x) { dmin_x = d.absmin_x; }
  324.          if (d.absmax_x > dmax_x) { dmax_x = d.absmax_x; }
  325.          if (d.absmin_y < dmin_y) { dmin_y = d.absmin_y; }
  326.          if (d.absmax_y > dmax_y) { dmax_y = d.absmax_y; }
  327.          if (d.absmin_z < dmin_z) { dmin_z = d.absmin_z; }
  328.          if (d.absmax_z > dmax_z) { dmax_z = d.absmax_z; }
  329.          d = d.enemy; // next linked door;
  330.       } while ((d != d_master) && (d != world));
  331.    }
  332.    else {
  333.       // secret doors
  334.       // we ignore these currently
  335.       return;
  336.    }
  337.  
  338.    {
  339.       local float is_x,is_y,is_z,set;
  340.       local vector dir,or;
  341.       set = is_x = is_y = is_z = FALSE;
  342.       or = player.origin;
  343.       if (dmin_x + 15 < player.absmin_x && player.absmax_x < dmax_x - 15) is_x = TRUE;
  344.       if (dmin_y + 15 < player.absmin_y && player.absmax_y < dmax_y - 15) is_y = TRUE;
  345.       if (dmin_z + 15 < player.absmin_z && player.absmax_z < dmax_z - 15) is_z = TRUE;
  346.       // dprint("doors:  "); dprint (vtos(dmin)); dprint (" "); dprint (vtos(dmax)); dprint ("\n");
  347.       // dprint("player: "); dprint (vtos(player.absmin)); dprint (" "); dprint (vtos(player.absmax)); dprint ("\n");
  348.       if (is_x && is_y) {
  349.          // dprint("door is in xy plane\n");
  350.          if      (or_z < dmin_z) { dir = '0 0  1'; or_z = dmax_z + 25; }
  351.          else if (or_z > dmax_z) { dir = '0 0 -1'; or_z = dmin_z - 25; }
  352.          set = TRUE;
  353.       }
  354.       else if (is_x && is_z) {
  355.          // dprint("door is in xz plane\n");
  356.          if      (or_y < dmin_y) { dir = '0  1 0'; or_y = dmax_y + 25; }
  357.          else if (or_y > dmax_y) { dir = '0 -1 0'; or_y = dmin_y - 25; }
  358.          set = TRUE;
  359.       }
  360.       else if (is_y && is_z) {
  361.          // dprint("door is in yz plane\n");
  362.          if      (or_x < dmin_x) { dir = ' 1 0 0'; or_x = dmax_x + 25; }
  363.          else if (or_x > dmax_x) { dir = '-1 0 0'; or_x = dmin_x - 25; }
  364.          set = TRUE;
  365.       }
  366.       if (set) { 
  367.          local vector v;
  368.          v =  normalize(player.velocity);
  369.          if (dir * v < 0.5) return;
  370.          player.origin = or;
  371.          setorigin (player, player.origin);
  372.       }
  373.    }
  374. };
  375.  
  376. void(entity player,entity tele) ObserverTeleportThroughTeleporter =
  377. {
  378.  
  379.    {
  380.       local vector v1,v2;
  381.       v1 = ((tele.absmax + tele.absmin) * 0.5) - player.origin; normalize(v1);
  382.       v2 = player.velocity; normalize(v2);
  383.       if (v1 * v2 <= 0.1) return;
  384.    }
  385.  
  386.    local entity targ;
  387.    targ = find (world, targetname, tele.target);
  388.    if (!targ) objerror ("ObserverTeleportThroughTeleporter: couldn't find teleporter target");
  389.    makevectors (targ.mangle);
  390.    setorigin (player, targ.origin);
  391.    player.angles = targ.mangle;
  392.    player.fixangle = TRUE; // turn this way immediately
  393.    player.teleport_time = time + 0.7;
  394.    player.velocity = v_forward * 300;
  395.    // player.flags = player.flags - player.flags & FL_ONGROUND;
  396. };
  397.  
  398.  
  399.