Backpack Tossing Revised


Posted by Maj.Bitch (24.95.222.*) at 6:42 PM, 4/29/2001:


If you're using this feature in your mod, give these new routines a test run!


First, add this to the bottom of your edict_t struct:

  int packitems[256];

Now, paste in these new routines right above your player_die() function:

//=====================================================
//=====================================================
//=====================================================

//=====================================================
void Backpack_Touch(edict_t *pack,edict_t *other,cplane_t *plane,csurface_t *surface) {

  if (!other || !other->client || pack->owner==other) return;

  gi.sound(other,3,gi.soundindex("items/pkup.wav"),1.0,1,0);

  for (int i=1; i<game.num_items; i++) {
    int quantity=pack->packitems[i];
    if (quantity<=0) continue;
    if (itemlist[i].flags & IT_WEAPON)
      other->client->pers.inventory[ITEM_INDEX(&itemlist[i])]=1;
    else
      other->client->pers.inventory[ITEM_INDEX(&itemlist[i])]+=quantity; }

  G_FreeEdict(pack);
}

//=====================================================
void G_FreePack(edict_t *pack) {
  G_MuzzleFlash(pack-g_edicts,pack->s.origin,MZ_RESPAWN);
  G_FreeEdict(pack);
}

//=====================================================
void TossClientBackpack(edict_t *player) {
vec3_t forward,up;

  if (gi.pointcontents(player->s.origin) & (CONTENTS_LAVA|CONTENTS_SLIME))
    return; // don't toss pack if in lava/slime

  edict_t *pack=G_Spawn();
  pack->owner=player;
  pack->s.modelindex=gi.modelindex("models/items/pack/tris.md2");
  pack->s.effects|=EF_ROTATE;
  pack->s.renderfx|=RF_GLOW;
  pack->movetype=MOVETYPE_BOUNCE;
  pack->solid=SOLID_TRIGGER;
  VectorSet(pack->mins,-16,-16,-16);
  VectorSet(pack->maxs,16,16,16);
  VectorCopy(player->s.origin,pack->s.origin);
  VectorSet(pack->velocity,1,1,1);
  AngleVectors(player->s.angles,forward,NULL,up);
  VectorMA(pack->velocity,100+crandom()*10.0,forward,pack->velocity);
  VectorMA(pack->velocity,200+crandom()*10.0,up,pack->velocity);

  for (int i=1; i<game.num_items; i++) {
    int quantity=player->client->pers.inventory[ITEM_INDEX(&itemlist[i])];
    if (quantity>0)
      pack->packitems[i]+=quantity; } // stuff the pack with items

  pack->touch=Backpack_Touch;

  pack->think=G_FreePack;
  pack->nextthink=level.time + 15.0;

  gi.linkentity(pack);
}


Lastly, inside of your player_die() function, replace the TossClientWeapon() function call with your new TossClientBackpack() function and you're done!

Hint: Suicide near a respawn point and immediately respawn there and watch the pack bounce around AND be sure to watch the neat effect when the pack disappears in 15 seconds when nobody picks it up.

Maj.Bitch