home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2000 March / maximum-cd-2000-03.iso / Quake3 Game Source / Q3AGameSource.exe / Main / g_misc.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-01-18  |  8.3 KB  |  310 lines

  1. // Copyright (C) 1999-2000 Id Software, Inc.
  2. //
  3. // g_misc.c
  4.  
  5. #include "g_local.h"
  6.  
  7.  
  8. /*QUAKED func_group (0 0 0) ?
  9. Used to group brushes together just for editor convenience.  They are turned into normal brushes by the utilities.
  10. */
  11.  
  12.  
  13. /*QUAKED info_camp (0 0.5 0) (-4 -4 -4) (4 4 4)
  14. Used as a positional target for calculations in the utilities (spotlights, etc), but removed during gameplay.
  15. */
  16. void SP_info_camp( gentity_t *self ) {
  17.     G_SetOrigin( self, self->s.origin );
  18. }
  19.  
  20.  
  21. /*QUAKED info_null (0 0.5 0) (-4 -4 -4) (4 4 4)
  22. Used as a positional target for calculations in the utilities (spotlights, etc), but removed during gameplay.
  23. */
  24. void SP_info_null( gentity_t *self ) {
  25.     G_FreeEntity( self );
  26. }
  27.  
  28.  
  29. /*QUAKED info_notnull (0 0.5 0) (-4 -4 -4) (4 4 4)
  30. Used as a positional target for in-game calculation, like jumppad targets.
  31. target_position does the same thing
  32. */
  33. void SP_info_notnull( gentity_t *self ){
  34.     G_SetOrigin( self, self->s.origin );
  35. }
  36.  
  37.  
  38. /*QUAKED light (0 1 0) (-8 -8 -8) (8 8 8) linear
  39. Non-displayed light.
  40. "light" overrides the default 300 intensity.
  41. Linear checbox gives linear falloff instead of inverse square
  42. Lights pointed at a target will be spotlights.
  43. "radius" overrides the default 64 unit radius of a spotlight at the target point.
  44. */
  45. void SP_light( gentity_t *self ) {
  46.     G_FreeEntity( self );
  47. }
  48.  
  49.  
  50.  
  51. /*
  52. =================================================================================
  53.  
  54. TELEPORTERS
  55.  
  56. =================================================================================
  57. */
  58.  
  59. void TeleportPlayer( gentity_t *player, vec3_t origin, vec3_t angles ) {
  60.     gentity_t    *tent;
  61.  
  62.     // use temp events at source and destination to prevent the effect
  63.     // from getting dropped by a second player event
  64.     if ( player->client->sess.sessionTeam != TEAM_SPECTATOR ) {
  65.         tent = G_TempEntity( player->client->ps.origin, EV_PLAYER_TELEPORT_OUT );
  66.         tent->s.clientNum = player->s.clientNum;
  67.  
  68.         tent = G_TempEntity( origin, EV_PLAYER_TELEPORT_IN );
  69.         tent->s.clientNum = player->s.clientNum;
  70.     }
  71.  
  72.     // unlink to make sure it can't possibly interfere with G_KillBox
  73.     trap_UnlinkEntity (player);
  74.  
  75.     VectorCopy ( origin, player->client->ps.origin );
  76.     player->client->ps.origin[2] += 1;
  77.  
  78.     // spit the player out
  79.     AngleVectors( angles, player->client->ps.velocity, NULL, NULL );
  80.     VectorScale( player->client->ps.velocity, 400, player->client->ps.velocity );
  81.     player->client->ps.pm_time = 160;        // hold time
  82.     player->client->ps.pm_flags |= PMF_TIME_KNOCKBACK;
  83.  
  84.     // toggle the teleport bit so the client knows to not lerp
  85.     player->client->ps.eFlags ^= EF_TELEPORT_BIT;
  86.  
  87.     // set angles
  88.     SetClientViewAngle( player, angles );
  89.  
  90.     // kill anything at the destination
  91.     if ( player->client->sess.sessionTeam != TEAM_SPECTATOR ) {
  92.         G_KillBox (player);
  93.     }
  94.  
  95.     // save results of pmove
  96.     BG_PlayerStateToEntityState( &player->client->ps, &player->s, qtrue );
  97.  
  98.     // use the precise origin for linking
  99.     VectorCopy( player->client->ps.origin, player->r.currentOrigin );
  100.  
  101.     if ( player->client->sess.sessionTeam != TEAM_SPECTATOR ) {
  102.         trap_LinkEntity (player);
  103.     }
  104. }
  105.  
  106.  
  107. /*QUAKED misc_teleporter_dest (1 0 0) (-32 -32 -24) (32 32 -16)
  108. Point teleporters at these.
  109. Now that we don't have teleport destination pads, this is just
  110. an info_notnull
  111. */
  112. void SP_misc_teleporter_dest( gentity_t *ent ) {
  113. }
  114.  
  115.  
  116. //===========================================================
  117.  
  118. /*QUAKED misc_model (1 0 0) (-16 -16 -16) (16 16 16)
  119. "model"        arbitrary .md3 file to display
  120. */
  121. void SP_misc_model( gentity_t *ent ) {
  122.  
  123. #if 0
  124.     ent->s.modelindex = G_ModelIndex( ent->model );
  125.     VectorSet (ent->mins, -16, -16, -16);
  126.     VectorSet (ent->maxs, 16, 16, 16);
  127.     trap_LinkEntity (ent);
  128.  
  129.     G_SetOrigin( ent, ent->s.origin );
  130.     VectorCopy( ent->s.angles, ent->s.apos.trBase );
  131. #else
  132.     G_FreeEntity( ent );
  133. #endif
  134. }
  135.  
  136. //===========================================================
  137.  
  138. void locateCamera( gentity_t *ent ) {
  139.     vec3_t        dir;
  140.     gentity_t    *target;
  141.     gentity_t    *owner;
  142.  
  143.     owner = G_PickTarget( ent->target );
  144.     if ( !owner ) {
  145.         G_Printf( "Couldn't find target for misc_partal_surface\n" );
  146.         G_FreeEntity( ent );
  147.         return;
  148.     }
  149.     ent->r.ownerNum = owner->s.number;
  150.  
  151.     // frame holds the rotate speed
  152.     if ( owner->spawnflags & 1 ) {
  153.         ent->s.frame = 25;
  154.     } else if ( owner->spawnflags & 2 ) {
  155.         ent->s.frame = 75;
  156.     }
  157.  
  158.     // clientNum holds the rotate offset
  159.     ent->s.clientNum = owner->s.clientNum;
  160.  
  161.     VectorCopy( owner->s.origin, ent->s.origin2 );
  162.  
  163.     // see if the portal_camera has a target
  164.     target = G_PickTarget( owner->target );
  165.     if ( target ) {
  166.         VectorSubtract( target->s.origin, owner->s.origin, dir );
  167.         VectorNormalize( dir );
  168.     } else {
  169.         G_SetMovedir( owner->s.angles, dir );
  170.     }
  171.  
  172.     ent->s.eventParm = DirToByte( dir );
  173. }
  174.  
  175. /*QUAKED misc_portal_surface (0 0 1) (-8 -8 -8) (8 8 8)
  176. The portal surface nearest this entity will show a view from the targeted misc_portal_camera, or a mirror view if untargeted.
  177. This must be within 64 world units of the surface!
  178. */
  179. void SP_misc_portal_surface(gentity_t *ent) {
  180.     VectorClear( ent->r.mins );
  181.     VectorClear( ent->r.maxs );
  182.     trap_LinkEntity (ent);
  183.  
  184.     ent->r.svFlags = SVF_PORTAL;
  185.     ent->s.eType = ET_PORTAL;
  186.  
  187.     if ( !ent->target ) {
  188.         VectorCopy( ent->s.origin, ent->s.origin2 );
  189.     } else {
  190.         ent->think = locateCamera;
  191.         ent->nextthink = level.time + 100;
  192.     }
  193. }
  194.  
  195. /*QUAKED misc_portal_camera (0 0 1) (-8 -8 -8) (8 8 8) slowrotate fastrotate
  196. The target for a misc_portal_director.  You can set either angles or target another entity to determine the direction of view.
  197. "roll" an angle modifier to orient the camera around the target vector;
  198. */
  199. void SP_misc_portal_camera(gentity_t *ent) {
  200.     float    roll;
  201.  
  202.     VectorClear( ent->r.mins );
  203.     VectorClear( ent->r.maxs );
  204.     trap_LinkEntity (ent);
  205.  
  206.     G_SpawnFloat( "roll", "0", &roll );
  207.  
  208.     ent->s.clientNum = roll/360.0 * 256;
  209. }
  210.  
  211. /*
  212. ======================================================================
  213.  
  214.   SHOOTERS
  215.  
  216. ======================================================================
  217. */
  218.  
  219. void Use_Shooter( gentity_t *ent, gentity_t *other, gentity_t *activator ) {
  220.     vec3_t        dir;
  221.     float        deg;
  222.     vec3_t        up, right;
  223.  
  224.     // see if we have a target
  225.     if ( ent->enemy ) {
  226.         VectorSubtract( ent->enemy->r.currentOrigin, ent->s.origin, dir );
  227.         VectorNormalize( dir );
  228.     } else {
  229.         VectorCopy( ent->movedir, dir );
  230.     }
  231.  
  232.     // randomize a bit
  233.     PerpendicularVector( up, dir );
  234.     CrossProduct( up, dir, right );
  235.  
  236.     deg = crandom() * ent->random;
  237.     VectorMA( dir, deg, up, dir );
  238.  
  239.     deg = crandom() * ent->random;
  240.     VectorMA( dir, deg, right, dir );
  241.  
  242.     VectorNormalize( dir );
  243.  
  244.     switch ( ent->s.weapon ) {
  245.     case WP_GRENADE_LAUNCHER:
  246.         fire_grenade( ent, ent->s.origin, dir );
  247.         break;
  248.     case WP_ROCKET_LAUNCHER:
  249.         fire_rocket( ent, ent->s.origin, dir );
  250.         break;
  251.     case WP_PLASMAGUN:
  252.         fire_plasma( ent, ent->s.origin, dir );
  253.         break;
  254.     }
  255.  
  256.     G_AddEvent( ent, EV_FIRE_WEAPON, 0 );
  257. }
  258.  
  259.  
  260. static void InitShooter_Finish( gentity_t *ent ) {
  261.     ent->enemy = G_PickTarget( ent->target );
  262.     ent->think = 0;
  263.     ent->nextthink = 0;
  264. }
  265.  
  266. void InitShooter( gentity_t *ent, int weapon ) {
  267.     ent->use = Use_Shooter;
  268.     ent->s.weapon = weapon;
  269.  
  270.     RegisterItem( BG_FindItemForWeapon( weapon ) );
  271.  
  272.     G_SetMovedir( ent->s.angles, ent->movedir );
  273.  
  274.     if ( !ent->random ) {
  275.         ent->random = 1.0;
  276.     }
  277.     ent->random = sin( M_PI * ent->random / 180 );
  278.     // target might be a moving object, so we can't set movedir for it
  279.     if ( ent->target ) {
  280.         ent->think = InitShooter_Finish;
  281.         ent->nextthink = level.time + 500;
  282.     }
  283.     trap_LinkEntity( ent );
  284. }
  285.  
  286. /*QUAKED shooter_rocket (1 0 0) (-16 -16 -16) (16 16 16)
  287. Fires at either the target or the current direction.
  288. "random" the number of degrees of deviance from the taget. (1.0 default)
  289. */
  290. void SP_shooter_rocket( gentity_t *ent ) {
  291.     InitShooter( ent, WP_ROCKET_LAUNCHER );
  292. }
  293.  
  294. /*QUAKED shooter_plasma (1 0 0) (-16 -16 -16) (16 16 16)
  295. Fires at either the target or the current direction.
  296. "random" is the number of degrees of deviance from the taget. (1.0 default)
  297. */
  298. void SP_shooter_plasma( gentity_t *ent ) {
  299.     InitShooter( ent, WP_PLASMAGUN);
  300. }
  301.  
  302. /*QUAKED shooter_grenade (1 0 0) (-16 -16 -16) (16 16 16)
  303. Fires at either the target or the current direction.
  304. "random" is the number of degrees of deviance from the taget. (1.0 default)
  305. */
  306. void SP_shooter_grenade( gentity_t *ent ) {
  307.     InitShooter( ent, WP_GRENADE_LAUNCHER);
  308. }
  309.  
  310.