// Functions for q3 weapon dropping by [SuB]paranoid, paranoid@planetstealth.de // for use with my tutorial at www.planetquake.com/code3arena ( Tutorial 22 ). /* ============= ThrowWeapon XRAY FMJ ============= */ void ThrowWeapon( gentity_t *ent ) { gclient_t *client; usercmd_t *ucmd; gitem_t *xr_item; gentity_t *xr_drop; byte i; int amount; client = ent->client; ucmd = &ent->client->pers.cmd; if( client->ps.weapon == WP_GAUNTLET || client->ps.weapon == WP_MACHINEGUN || client->ps.weapon == WP_GRAPPLING_HOOK || ( ucmd->buttons & BUTTON_ATTACK )) return; xr_item = BG_FindItemForWeapon( client->ps.weapon ); amount= client->ps.ammo[ client->ps.weapon ]; // XRAY save amount client->ps.ammo[ client->ps.weapon ] = 0; client->ps.stats[STAT_WEAPONS] &= ~( 1 << client->ps.weapon ); client->ps.weapon = WP_MACHINEGUN; for ( i = WP_NUM_WEAPONS - 1 ; i > 0 ; i-- ) { if ( client->ps.stats[STAT_WEAPONS] & ( 1 << i ) ) { client->ps.weapon = i; break; } } xr_drop= dropWeapon( ent, xr_item, 0, FL_DROPPED_ITEM | FL_THROWN_ITEM ); if( amount != 0) xr_drop->count= amount; else xr_drop->count= -1; // XRAY FMJ 0 is already taken, -1 means no ammo } // --- /* ================ dropWeapon XRAY FMJ ================ */ gentity_t *dropWeapon( gentity_t *ent, gitem_t *item, float angle, int xr_flags ) { // XRAY FMJ vec3_t velocity; vec3_t origin; VectorCopy( ent->s.pos.trBase, origin ); // set aiming directions AngleVectors (ent->client->ps.viewangles, velocity, NULL, NULL); origin[2] += ent->client->ps.viewheight; VectorMA( origin, 34, velocity, origin ); // 14 // snap to integer coordinates for more efficient network bandwidth usage SnapVector( origin); // extra vertical velocity velocity[2] += 0.2; VectorNormalize( velocity ); return LaunchItem( item, origin, velocity, xr_flags ); } // --- /* ================ LaunchItem Spawns an item and tosses it forward ================ */ gentity_t *LaunchItem( gitem_t *item, vec3_t origin, vec3_t velocity, int xr_flags ) { gentity_t *dropped; dropped = G_Spawn(); dropped->s.eType = ET_ITEM; dropped->s.modelindex = item - bg_itemlist; // store item number in modelindex dropped->s.modelindex2 = 1; // This is non-zero is it's a dropped item dropped->classname = item->classname; dropped->item = item; VectorSet (dropped->r.mins, -ITEM_RADIUS, -ITEM_RADIUS, -ITEM_RADIUS); VectorSet (dropped->r.maxs, ITEM_RADIUS, ITEM_RADIUS, ITEM_RADIUS); dropped->r.contents = CONTENTS_TRIGGER; dropped->touch = Touch_Item; G_SetOrigin( dropped, origin ); dropped->s.pos.trType = TR_GRAVITY; dropped->s.pos.trTime = level.time; VectorCopy( velocity, dropped->s.pos.trDelta ); dropped->s.eFlags |= EF_BOUNCE_HALF; if (item->giType == IT_TEAM) { // Special case for CTF flags dropped->think = Team_DroppedFlagThink; dropped->nextthink = level.time + 30000; Team_CheckDroppedItem( dropped ); } else { // auto-remove after 30 seconds dropped->think = G_FreeEntity; dropped->nextthink = level.time + 30000; } dropped->flags = xr_flags; if( xr_flags & FL_THROWN_ITEM) { dropped->clipmask = MASK_SHOT; // XRAY FMJ dropped->s.pos.trTime = level.time - 50; // move a bit on the very first frame VectorScale( velocity, 500, dropped->s.pos.trDelta ); // 700 SnapVector( dropped->s.pos.trDelta ); // save net bandwidth dropped->physicsBounce= 0.65; } trap_LinkEntity (dropped); return dropped; } // EOF