Substitute bodyque system


Posted by Maj.Bitch (24.95.222.*) at 12:21 PM, 6/17/2001:

Here you go.. First, open your source and find these corresponding functions (I've indicated which ones won't exist) and delete them from your source. Second, cut and past all this stuff to the bottom of either your g_utils.c or g_func.c file. You may have to prototype some of the functions in your header file (but your compiler will tell you which undefined function references it needs). Other than that.. Everything else should remain the same.


//=====================================================
void SV_SetClientAnimation(edict_t *ent,int startframe,int endframe,int priority) {
  if (!ent->client) return;
  ent->client->anim_priority=priority;
  ent->s.frame=startframe;
  ent->client->anim_end=endframe;
  gi.linkentity(ent);
}

//========================================================
//============== PLAYER GIB HANDLING STUFF ===============
//========================================================

//========================================================
void gib_touch(edict_t *gib,edict_t *other,cplane_t *plane,csurface_t *surf) {
  if (other==world) return;
  G_FreeEdict(gib);
}

//========================================================
void gib_think(edict_t *gib) {

  if (gib->s.effects!=EF_FLIES) // skip if already has flies effects
    if (gib->random<=5.0) {
      if (VectorLength(gib->velocity)<1) // only start flies when gib stops moving
        if (!(gi.pointcontents(gib->s.origin) & MASK_WATER)) { // no flies in water
          gib->s.effects=EF_FLIES;
          gib->wait=level.time + 15.0; } } // extend timer to show flies effect

  if (gib->wait<=level.time) {
    G_FreeEdict(gib);
    return; }

  gib->nextthink=level.time + 0.2;
}

//========================================================
void ThrowGib(edict_t *self,char *gibname) {
vec3_t origin;
edict_t *gib;

  gib=G_Spawn();
  gi.setmodel(gib,gibname);
  gib->solid=SOLID_BBOX;
  gib->s.effects|=EF_GIB;
  gib->flags|=FL_NO_KNOCKBACK;
  gib->takedamage=DAMAGE_NO;
  gib->random=(float)(rand()&10);

  //----------------------------------------------------------//
  if (!strcmp(gibname,"models/objects/gibs/sm_meat/tris.md2")
   || !strcmp(gibname,"models/objects/gibs/bone/tris.md2")
   || !strcmp(gibname,"models/objects/gibs/bone2/tris.md2"))
    gib->movetype=MOVETYPE_TOSS; // these gib models don't bounce
  else
    gib->movetype=MOVETYPE_BOUNCE;

  //----------------------------------------------------------//
  VectorCopy(self->s.origin,origin);
  gib->s.origin[0]=origin[0]+crandom()*self->size[0];
  gib->s.origin[1]=origin[1]+crandom()*self->size[1];
  gib->s.origin[2]=(rand()%10)+origin[2]+crandom()*self->size[2];
  if (self->velocity[0] || self->velocity[1])
    VectorCopy(self->velocity,gib->velocity); // make gib fly in player's last direction
  else
    VectorSet(gib->velocity,crandom()*200,crandom()*200,0); // else random directions
  if (self->velocity[2]>=0) gib->velocity[2]=200;
  VectorScale(gib->velocity,random(),gib->velocity);
  //----------------------------------------------------------//

  gib->wait=level.time + 10.0; // free gib model in 10 secs

  gib->touch=gib_touch; // free if gib is touched

  gib->think=gib_think;
  gib->nextthink=level.time + 0.1;

  gi.linkentity(gib);
}

//========================================================
//============= THROWING BODY PARTS AROUND ===============
//========================================================

//========================================================
void ThrowBodyParts(edict_t *self) { // WON'T EXIST
int n;

  gi.sound(self,4,gi.soundindex("misc/udeath.wav"),1,1);

  // Feel free to change the amounts of bodyparts tossed..

  for (n=0;n<2;n++)
    ThrowGib(self,"models/objects/gibs/sm_meat/tris.md2");
  for (n=0;n<2;n++)
    ThrowGib(self,"models/objects/gibs/bone/tris.md2");
  for (n=0;n<1;n++)
    ThrowGib(self,"models/objects/gibs/skull/tris.md2");
  for (n=0;n<2;n++)
    ThrowGib(self,"models/objects/gibs/arm/tris.md2");
  for (n=0;n<1;n++)
    ThrowGib(self,"models/objects/gibs/chest/tris.md2");
  for (n=0;n<2;n++)
    ThrowGib(self,"models/objects/gibs/leg/tris.md2");
  for (n=0;n<2;n++)
    ThrowGib(self,"models/objects/gibs/bone2/tris.md2");
  for (n=0;n<2;n++)
    ThrowGib(self,"models/objects/gibs/sm_meat/tris.md2");
}

//========================================================
void ThrowClientHead(edict_t *self) {
vec3_t vbottom;

  if (self->svflags & SVF_NOCLIENT) {
    G_FreeEdict(self);
    return; }

  VectorCopy(self->s.origin,vbottom);
  vbottom[2]-=(abs(self->mins[2])+3.0); // check contents at foot level

  // Only toss body parts if player DID NOT die in lava/slime
  if (!(gi.pointcontents(vbottom) & (CONTENTS_LAVA|CONTENTS_SLIME)))
    ThrowBodyParts(self);

  self->svflags|=SVF_NOCLIENT;

  SV_SetClientAnimation(self,0,0,5);
}

//========================================================
//============== PLAYER BODY QUEUE HANDLING ==============
//========================================================

// You may already have this function in your source..
//=====================================================
void G_MuzzleFlash(int rec_no,vec3_t origin,int flashnum) {
  gi.WriteByte(1);
  gi.WriteShort((short)rec_no);
  gi.WriteByte(flashnum);
  gi.multicast(origin,MULTICAST_PVS);
}

//========================================================
void body_free(edict_t *body) { // MIGHT NOT EXIST

  if (!(body->svflags & SVF_NOCLIENT)) // if player back in game
    G_MuzzleFlash(body-g_edicts,body->s.origin,11); // do sparkle effect when body is removed from game

  G_FreeEdict(body);
}

//========================================================
void body_think(edict_t *body) { // MIGHT NOT EXIST

  if ((body->wait<=level.time) || (body->owner && !(body->owner->svflags & SVF_NOCLIENT))) {
    body_free(body); // free body at moment player respawn back into game
    return; }

  body->nextthink=level.time + 0.1;
}

//========================================================
void body_touch(edict_t *body,edict_t *other,cplane_t *plane,csurface_t *surf) {
  if (other==world) return;
  G_FreeEdict(body); // disappear if touched by other
}

//========================================================
void CopyToBodyQue(edict_t *ent) {
edict_t *body;

  gi.unlinkentity(ent); // must unlink player's edict_t struct first! - don't unlink to see what happens.. pretty interesting...

  body=G_Spawn();
  body->owner=ent;
  body->s=ent->s;
  body->takedamage=DAMAGE_NO;
  body->s.number=body-g_edicts;
  body->svflags|=ent->svflags;
  VectorCopy(ent->mins,body->mins);
  VectorCopy(ent->maxs,body->maxs);
  VectorCopy(ent->absmin,body->absmin);
  VectorCopy(ent->absmax,body->absmax);
  VectorCopy(ent->size,body->size);
  body->solid=ent->solid;
  body->clipmask=ent->clipmask;
  body->movetype=ent->movetype;

  body->wait=level.time + 10.0; // auto-free in 10 secs if player doesn't rejoin game first

  body->touch=body_touch; // free body

  body->think=body_think;
  body->nextthink=level.time + 0.1;

  gi.linkentity(body);
}

Let me know how you make out!

Have fun!

Maj.Bitch