LaserDrone Weapon


Posted by Maj.Bitch (24.95.222.*) at 4:23 PM, 1/12/2001:

Here it is... I tested it out on a clean Q2 v320 source and it works fine..

First, bind a key like so in g_cmds.c and prototype the Launch_LaserDrone() function..

else if (Q_stricmp (cmd, "drone") == 0)
Launch_LaserDrone(ent);

Next, create a new file called Drone.c and paste in ALL this source. Add the file to your project and sit back smile and compile!!
<C&NBSP;CODE>

#include "g_local.h"

//======================================================
//============ ARIAL LASERDRONE WEAPON =================
//======================================================
#define MOD_LASERDRONE 44 // put in g_local.h and use for ClientObituaries()

//======================================================
void LaserDrone_Fire(edict_t *LaserDrone, edict_t *target){
vec3_t start,end;

  VectorCopy(LaserDrone->s.origin, start);

  // some minor adjustments to positioning
  start[2] += 70;

  // Fire the laser beam.
  gi.WriteByte(svc_temp_entity);
  gi.WriteByte(TE_BFG_LASER
  gi.WritePosition(start);
  gi.WritePosition(end);
  gi.multicast(target->s.origin, MULTICAST_PVS);


  // Apply 80 damage units to victim..
  T_Damage(target, LaserDrone, LaserDrone, tv(0,0,0), start, tv(0,0,0), 80, 1, 0, MOD_LASERDRONE);

  // Must play sound AFTER firing else targeting accuracy affected(??)
  gi.sound(LaserDrone, CHAN_VOICE, gi.soundindex("weapons/laser2.wav"), 1.0, ATTN_NORM, 0);
}

//======================================================
void LaserDrone_Destruct(edict_t *LaserDrone) {

  // Blow up the LaserDrone Unit..
  gi.WriteByte(svc_temp_entity);
  gi.WriteByte(TE_EXPLOSION1);
  gi.WritePosition(LaserDrone->s.origin);
  gi.multicast(LaserDrone->s.origin, MULTICAST_PHS);

  // Give radius damage to anybody close by the explosion
  T_RadiusDamage(LaserDrone, world, 80, NULL, 300, MOD_SPLASH);

  G_FreeEdict(LaserDrone); // Free the LaserDrone entity.
}

//======================================================
void LaserDrone_Touch(edict_t *LaserDrone, edict_t *other, cplane_t *plane, csurface_t *surface)
{ // Dummy
}

//=========================================================
void LaserDrone_Die(edict_t *targ, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point)
{ // Dummy
}

//======================================================
// True if LaserDrone has been deactivated(exploded!).
//======================================================
qboolean DeActivated(edict_t *LaserDrone) {

  // Has time expired?
  if (LaserDrone->delay < level.time) {
    LaserDrone_Destruct(LaserDrone);
    return true; }
  else
    return false;
}

//==========================================================
// Search and Fire at all visible ents..(VERY FAST!)
//==========================================================
void LaserDrone_ThinkFast(edict_t *LaserDrone) {
edict_t *ent=NULL;
float radius=1000;

  if (DeActivated(LaserDrone)) return;  // Drone has exploded!

  while ((ent=findradius(ent, LaserDrone->s.origin, radius))!= NULL) {
    if (ent->health<=0) continue;
    if (!ent->takedamage) continue;
    if (!visible(LaserDrone,ent)) continue;
    // Targeting radius decreases with health of LaserDrone.
    radius=LaserDrone->wait*(LaserDrone->health/LaserDrone->max_health);
    LaserDrone_Fire(LaserDrone,ent); }

  // Initiate Re-targeting on next frame.
  LaserDrone->nextthink = level.time + 1.0;
}

//======================================================
void Activate_LaserDrone(edict_t *LaserDrone) {

  // Drone can take damage upon activation..
  LaserDrone->takedamage = DAMAGE_YES;

  // Start rotating the drone.
  LaserDrone->s.effects = EF_ROTATE;

  // Play Drone activation sound..
  gi.sound(LaserDrone, CHAN_VOICE, gi.soundindex("world/boss3/W_loop.wav"), 1.0, ATTN_NORM, 0);

  LaserDrone->think = LaserDrone_ThinkFast; // Use the FAST TARGETING routine.
  LaserDrone->nextthink = level.time + 0.1;
}

//======================================================
void Launch_LaserDrone(edict_t *ent) {
edict_t *LaserDrone;
int x, y;
vec3_t last_angles;

  x=(random()>0.5?-1:1);
  y=(random()>0.5?-1:1);

  VectorClear(last_angles);

  LaserDrone = G_Spawn();

  LaserDrone->classname = "LaserDrone";

  // For now, use ent's origin - NEED RANDOM ORIGINS
  VectorCopy(ent->s.origin, LaserDrone->s.origin);
  VectorCopy(ent->s.old_origin, LaserDrone->s.old_origin);

  LaserDrone->s.origin[0] += (random()*20+1)*x;
  LaserDrone->s.origin[1] += (random()*20+1)*y;
  LaserDrone->s.origin[2] += ent->viewheight+8;

  VectorCopy(ent->move_angles,last_angles);

  LaserDrone->velocity[2] = (random()*40);
  LaserDrone->velocity[1] = ((int)((random()*40)+10+last_angles[YAW])%60)*y;
  LaserDrone->velocity[0] = ((int)((random()*40)+20+last_angles[PITCH])%60)*x;
  VectorCopy(LaserDrone->velocity, last_angles);

  LaserDrone->movetype = MOVETYPE_FLY;// Float around gently.
  LaserDrone->solid = SOLID_BBOX;     // Enable touch capability.
  LaserDrone->takedamage = DAMAGE_NO; // No Damage until Activation.
  LaserDrone->clipmask = MASK_SHOT;   // Ability to be hit by weapon fire.

  LaserDrone->s.modelindex = gi.modelindex("models/items/keys/target/tris.md2");

  VectorSet(LaserDrone->mins, -20, -20, -40); // size of bbox for touch
  VectorSet(LaserDrone->maxs, 20, 20, 60);    // size of bbox for touch

  LaserDrone->health=200; // titanium hull makes it tough to kill!!
  LaserDrone->max_health=200;
  LaserDrone->wait=1200;  // Used as search radius var!!

  LaserDrone->delay = level.time + 65.0;

  LaserDrone->die=LaserDrone_Die;

  LaserDrone->touch=LaserDrone_Touch; // Dummy Function..

  LaserDrone->think = Activate_LaserDrone; // Done only once!

  LaserDrone->nextthink = level.time + 5.0; // 5 Sec delay before Activation..

  gi.linkentity(LaserDrone);

  gi.centerprintf(ent,"LaserDrone Launched\n\nMOVE AWAY NOW!!\n\n5 secs to Activation!\n");

  gi.sound(LaserDrone, CHAN_VOICE, gi.soundindex("world/airhiss1.wav"), 1.0, ATTN_NORM, 0);
}
</C&NBSP;CODE>

Right now it is set up to spawn infront (and above) the player entity who executes the launch command from the console. But, if you want these to spawn automatically you'll need to have some function to spawn these at random (and valid) locations automatically..

Have fun!!

Maj.Bitch