예제 #1
0
/**
* @brief Pick a weapon up.
*/
int Pickup_Weapon(gentity_t *ent, gentity_t *other)
{
    int      quantity;
    qboolean alreadyHave = qfalse;

    // magic ammo for any two-handed weapon
    if (ent->item->giTag == WP_AMMO)
    {
        AddMagicAmmo(other, ent->count);
        if (ent->parent && ent->parent->client)
        {
            other->client->pers.lastammo_client = ent->parent->s.clientNum;
        }

        // if LT isn't giving ammo to self or another LT or the enemy, give him some props
        if (other->client->ps.stats[STAT_PLAYER_CLASS] != PC_FIELDOPS)
        {
            if (ent->parent && ent->parent->client && other->client->sess.sessionTeam == ent->parent->client->sess.sessionTeam)
            {
                if (!(ent->parent->client->PCSpecialPickedUpCount % LT_SPECIAL_PICKUP_MOD))
                {
                    AddScore(ent->parent, WOLF_AMMO_UP);
                    if (ent->parent && ent->parent->client)
                    {
                        G_LogPrintf("Ammo_Pack: %d %d\n", (int)(ent->parent - g_entities), (int)(other - g_entities));
                    }
                }
                ent->parent->client->PCSpecialPickedUpCount++;
                G_AddSkillPoints(ent->parent, SK_SIGNALS, 1.f);
                G_DebugAddSkillPoints(ent->parent, SK_SIGNALS, 1.f, "ammo pack picked up");

#ifdef FEATURE_OMNIBOT
                //omni-bot event
                if (ent->parent)
                {
                    Bot_Event_RecievedAmmo(other - g_entities, ent->parent);
                }
#endif

                // extracted code originally here into AddMagicAmmo
                // add 1 clip of magic ammo for any two-handed weapon
            }
            return RESPAWN_NEVER;
        }
    }

    quantity = ent->count;

    // check if player already had the weapon
    alreadyHave = COM_BitCheck(other->client->ps.weapons, ent->item->giTag);

    // prevents drop/pickup weapon "quick reload" exploit
    if (alreadyHave)
    {
        Add_Ammo(other, ent->item->giTag, quantity, qfalse);

        // secondary weapon ammo
        if (ent->delay)
        {
            Add_Ammo(other, weaponTable[ent->item->giTag].weapAlts, ent->delay, qfalse);
        }
    }
    else
    {
        if (level.time - other->client->dropWeaponTime < 1000)
        {
            return 0;
        }

        // don't pick up when MG or mortar is set
        if (IS_MORTAR_WEAPON_SET(other->client->ps.weapon) || IS_MG_WEAPON_SET(other->client->ps.weapon))
        {
            return 0;
        }

        // see if we can pick it up
        if (G_CanPickupWeapon(ent->item->giTag, other))
        {
            weapon_t primaryWeapon;

            if (other->client->sess.playerType == PC_SOLDIER && other->client->sess.skill[SK_HEAVY_WEAPONS] >= 4)
            {
                primaryWeapon = G_GetPrimaryWeaponForClientSoldier(ent->item->giTag, other->client);
            }
            else
            {
                primaryWeapon = G_GetPrimaryWeaponForClient(other->client);
            }

            // added parens around ambiguous &&
            if (primaryWeapon)
            {
                // drop our primary weapon
                G_DropWeapon(other, primaryWeapon);

                // now pickup the other one
                other->client->dropWeaponTime = level.time;

                // add the weapon
                COM_BitSet(other->client->ps.weapons, ent->item->giTag);

                // fixup mauser/sniper issues
                switch (ent->item->giTag)
                {
                case WP_FG42:
                    COM_BitSet(other->client->ps.weapons, WP_FG42SCOPE);
                    break;
                case  WP_GARAND:
                    COM_BitSet(other->client->ps.weapons, WP_GARAND_SCOPE);
                    break;
                case  WP_K43:
                    COM_BitSet(other->client->ps.weapons, WP_K43_SCOPE);
                    break;
                case  WP_MORTAR:
                    COM_BitSet(other->client->ps.weapons, WP_MORTAR_SET);
                    break;
                case  WP_MORTAR2:
                    COM_BitSet(other->client->ps.weapons, WP_MORTAR2_SET);
                    break;
                case  WP_MOBILE_MG42:
                    COM_BitSet(other->client->ps.weapons, WP_MOBILE_MG42_SET);
                    break;
                case WP_MOBILE_BROWNING:
                    COM_BitSet(other->client->ps.weapons, WP_MOBILE_BROWNING_SET);
                    break;
                case  WP_CARBINE:
                    COM_BitSet(other->client->ps.weapons, WP_M7);
                    break;
                case WP_KAR98:
                    COM_BitSet(other->client->ps.weapons, WP_GPG40);
                    break;
                default:
                    break;
                }

                other->client->ps.ammoclip[BG_FindClipForWeapon(ent->item->giTag)] = 0;
                other->client->ps.ammo[BG_FindAmmoForWeapon(ent->item->giTag)]     = 0;

                if (ent->item->giTag == WP_MORTAR || ent->item->giTag == WP_MORTAR2)
                {
                    other->client->ps.ammo[BG_FindClipForWeapon(ent->item->giTag)] = quantity;

                    // secondary weapon ammo
                    if (ent->delay)
                    {
                        Add_Ammo(other, weaponTable[ent->item->giTag].weapAlts, ent->delay, qfalse);
                    }
                }
                else
                {
                    other->client->ps.ammoclip[BG_FindClipForWeapon(ent->item->giTag)] = quantity;

                    // secondary weapon ammo
                    if (ent->delay)
                    {
                        other->client->ps.ammo[weaponTable[ent->item->giTag].weapAlts] = ent->delay;
                    }
                }
            }
        }
        else
        {
            return 0;
        }
    }

#ifdef FEATURE_OMNIBOT
    Bot_Event_AddWeapon(other->client->ps.clientNum, Bot_WeaponGameToBot(ent->item->giTag));
#endif

    return RESPAWN_NEVER;
}
예제 #2
0
// Set up snapshot merge based on this portal
qboolean G_smvRunCamera( gentity_t *ent ) {
	int id = ent->TargetFlag;
	int chargeTime, sprintTime, hintTime, weapHeat;
	playerState_t *tps, *ps;

	// Opt out if not a real MV portal
	if ( ent->tagParent == NULL || ent->tagParent->client == NULL ) {
		return( qfalse );
	}

	if ( ( ps = &ent->tagParent->client->ps ) == NULL ) {
		return( qfalse );
	}

	// If viewing client is no longer connected, delete this camera
	if ( ent->tagParent->client->pers.connected != CON_CONNECTED ) {
		G_FreeEntity( ent );
		return( qtrue );
	}

	// Also remove if the target player is no longer in the game playing
	if ( ent->target_ent->client->pers.connected != CON_CONNECTED ||
		 ent->target_ent->client->sess.sessionTeam == TEAM_SPECTATOR ) {
		G_smvLocateEntityInMVList( ent->tagParent, ent->target_ent - g_entities, qtrue );
		return( qtrue );
	}

	// Seems that depending on player's state, we pull from either r.currentOrigin, or s.origin
	//		if(!spec) then use: r.currentOrigin
	//		if(spec) then use:  s.origin
	//
	// This is true for both the portal origin and its target (origin2)
	//
	VectorCopy( ent->tagParent->s.origin, ent->s.origin );
	G_SetOrigin( ent, ent->s.origin );
	VectorCopy( ent->target_ent->r.currentOrigin, ent->s.origin2 );
	trap_LinkEntity( ent );

	// Only allow client ids 0 to (MAX_MVCLIENTS-1) to be updated with extra info
	if ( id >= MAX_MVCLIENTS ) {
		return( qtrue );
	}

	tps = &ent->target_ent->client->ps;

	if ( tps->stats[STAT_PLAYER_CLASS] == PC_ENGINEER ) {
		chargeTime = g_engineerChargeTime.value;
	} else if ( tps->stats[STAT_PLAYER_CLASS] == PC_MEDIC ) {
		chargeTime = g_medicChargeTime.value;
	} else if ( tps->stats[STAT_PLAYER_CLASS] == PC_FIELDOPS )                                                                                                {
		chargeTime = g_LTChargeTime.value;
	} else if ( tps->stats[STAT_PLAYER_CLASS] == PC_COVERTOPS )                                                                                                                                                                                               {
		chargeTime = g_covertopsChargeTime.value;
	} else { chargeTime = g_soldierChargeTime.value;}

	chargeTime = ( level.time - tps->classWeaponTime >= (int)chargeTime ) ? 0 : ( 1 + floor( 15.0f * (float)( level.time - tps->classWeaponTime ) / chargeTime ) );
	sprintTime = ( ent->target_ent->client->pmext.sprintTime >= 20000 ) ? 0.0f : ( 1 + floor( 7.0f * (float)ent->target_ent->client->pmext.sprintTime / 20000.0f ) );
	weapHeat   = floor( (float)tps->curWeapHeat * 15.0f / 255.0f );
	hintTime   = ( tps->serverCursorHint != HINT_BUILD && ( tps->serverCursorHintVal >= 255 || tps->serverCursorHintVal == 0 ) ) ?
				 0 : ( 1 + floor( 15.0f * (float)tps->serverCursorHintVal / 255.0f ) );

	// (Remaining bits)
	// ammo      : 0
	// ammo-1    : 0
	// ammiclip  : 0
	// ammoclip-1: 16
	id = MAX_WEAPONS - 1 - ( id * 2 );

	if ( tps->pm_flags & PMF_LIMBO ) {
		ps->ammo[id] = 0;
		ps->ammo[id - 1] = 0;
		ps->ammoclip[id - 1] = 0;
	} else {
		ps->ammo[id]  = ( ( ( ent->target_ent->health > 0 ) ? ent->target_ent->health : 0 ) & 0xFF ); // Meds up to 140 :(
		ps->ammo[id] |= ( hintTime & 0x0F ) << 8; // 4 bits for work on current item (dynamite, weapon repair, etc.)
		ps->ammo[id] |= ( weapHeat & 0x0F ) << 12; // 4 bits for weapon heat info

		ps->ammo[id - 1]  = tps->ammo[BG_FindAmmoForWeapon( tps->weapon )] & 0x3FF;   // 11 bits needed to cover 1500 Venom ammo
		ps->ammo[id - 1] |= ( BG_simpleWeaponState( tps->weaponstate ) & 0x03 ) << 11;  // 2 bits for current weapon state
		ps->ammo[id - 1] |= ( ( tps->persistant[PERS_HWEAPON_USE] ) ? 1 : 0 ) << 13;    // 1 bit for mg42 use
		ps->ammo[id - 1] |= ( BG_simpleHintsCollapse( tps->serverCursorHint, hintTime ) & 0x03 ) << 14; // 2 bits for cursor hints

//	G_Printf("tps->hint: %d, dr: %d, collapse: %d\n", tps->serverCursorHint, HINT_DOOR_ROTATING, G_simpleHintsCollapse(tps->serverCursorHint, hintTime));

		ps->ammoclip[id - 1]  = tps->ammoclip[BG_FindClipForWeapon( tps->weapon )] & 0x1FF;   // 9 bits to cover 500 Venom ammo clip
		ps->ammoclip[id - 1] |= ( chargeTime & 0x0F ) << 9;   // 4 bits for weapon charge time
		ps->ammoclip[id - 1] |= ( sprintTime & 0x07 ) << 13;  // 3 bits for fatigue
	}

	return( qtrue );
}
예제 #3
0
/**
* @brief Drop weapon.
*/
void G_DropWeapon(gentity_t *ent, weapon_t weapon)
{
    vec3_t    angles, velocity, org, offset, mins, maxs;
    gclient_t *client = ent->client;
    gentity_t *ent2;
    gitem_t   *item;
    trace_t   tr;

    if (!IS_VALID_WEAPON(weapon))
    {
        return;
    }

    item = BG_FindItemForWeapon(weapon);
    VectorCopy(client->ps.viewangles, angles);

    // clamp pitch
    if (angles[PITCH] < -30)
    {
        angles[PITCH] = -30;
    }
    else if (angles[PITCH] > 30)
    {
        angles[PITCH] = 30;
    }

    AngleVectors(angles, velocity, NULL, NULL);
    VectorScale(velocity, 64, offset);
    offset[2] += client->ps.viewheight / 2.f;
    VectorScale(velocity, 75, velocity);
    velocity[2] += 50 + random() * 35;

    VectorAdd(client->ps.origin, offset, org);

    VectorSet(mins, -ITEM_RADIUS, -ITEM_RADIUS, 0);
    VectorSet(maxs, ITEM_RADIUS, ITEM_RADIUS, 2 * ITEM_RADIUS);

    trap_Trace(&tr, client->ps.origin, mins, maxs, org, ent->s.number, MASK_SOLID);
    VectorCopy(tr.endpos, org);

    ent2 = LaunchItem(item, org, velocity, client->ps.clientNum);
    COM_BitClear(client->ps.weapons, weapon);

    switch (weapon)
    {
    case WP_KAR98:
        COM_BitClear(client->ps.weapons, WP_GPG40);
        break;
    case WP_CARBINE:
        COM_BitClear(client->ps.weapons, WP_M7);
        break;
    case WP_FG42:
        COM_BitClear(client->ps.weapons, WP_FG42SCOPE);
        break;
    case WP_K43:
        COM_BitClear(client->ps.weapons, WP_K43_SCOPE);
        break;
    case WP_GARAND:
        COM_BitClear(client->ps.weapons, WP_GARAND_SCOPE);
        break;
    case WP_MORTAR:
        COM_BitClear(client->ps.weapons, WP_MORTAR_SET);
        break;
    case WP_MORTAR2:
        COM_BitClear(client->ps.weapons, WP_MORTAR2_SET);
        break;
    case WP_MOBILE_MG42:
        COM_BitClear(client->ps.weapons, WP_MOBILE_MG42_SET);
        break;
    case WP_MOBILE_BROWNING:
        COM_BitClear(client->ps.weapons, WP_MOBILE_BROWNING_SET);
        break;
    default:
        break;
    }

    // Clear out empty weapon, change to next best weapon
    G_AddEvent(ent, EV_WEAPONSWITCHED, 0);

    if (weapon == client->ps.weapon)
    {
        client->ps.weapon = 0;
    }

    if (IS_MORTAR_WEAPON_SET(weapon))
    {
        ent2->count = client->ps.ammo[BG_FindAmmoForWeapon(weapon)] + client->ps.ammoclip[BG_FindClipForWeapon(weapon)];
    }
    else
    {
        ent2->count = client->ps.ammoclip[BG_FindClipForWeapon(weapon)];
    }

    if (weapon == WP_KAR98 || weapon == WP_CARBINE)
    {
        ent2->delay = client->ps.ammo[BG_FindAmmoForWeapon(weaponTable[weapon].weapAlts)];
    }
    else
    {
        ent2->delay = 0;
    }

    //  ent2->item->quantity = client->ps.ammoclip[BG_FindClipForWeapon(weapon)]; // um, modifying an item is not a good idea
    client->ps.ammoclip[BG_FindClipForWeapon(weapon)] = 0;

#ifdef FEATURE_OMNIBOT
    Bot_Event_RemoveWeapon(client->ps.clientNum, Bot_WeaponGameToBot(weapon));
#endif
}
예제 #4
0
int Pickup_Weapon( gentity_t *ent, gentity_t *other ) {
	int			quantity;
	qboolean	alreadyHave = qfalse;

	// JPW NERVE -- magic ammo for any two-handed weapon
	if( ent->item->giTag == WP_AMMO ) {
		AddMagicAmmo( other, ent->count );

		// if LT isn't giving ammo to self or another LT or the enemy, give him some props
		if( other->client->ps.stats[STAT_PLAYER_CLASS] != PC_FIELDOPS ) {
			if ( ent->parent && ent->parent->client && other->client->sess.sessionTeam == ent->parent->client->sess.sessionTeam ) {
				if (!(ent->parent->client->PCSpecialPickedUpCount % LT_SPECIAL_PICKUP_MOD)) {
					AddScore(ent->parent, WOLF_AMMO_UP);
					if(ent->parent && ent->parent->client) {
						G_LogPrintf("Ammo_Pack: %d %d\n", ent->parent - g_entities, other - g_entities);	// OSP
					}
				}
				ent->parent->client->PCSpecialPickedUpCount++;
				G_AddSkillPoints( ent->parent, SK_SIGNALS, 1.f );
				G_DebugAddSkillPoints( ent->parent, SK_SIGNALS, 1.f, "ammo pack picked up" ); 

				// extracted code originally here into AddMagicAmmo -xkan, 9/18/2002
				// add 1 clip of magic ammo for any two-handed weapon
			}
			return RESPAWN_SP;
		}
	}

	quantity = ent->count;

	// check if player already had the weapon
	alreadyHave = COM_BitCheck( other->client->ps.weapons, ent->item->giTag );

	// JPW NERVE  prevents drop/pickup weapon "quick reload" exploit
	if( alreadyHave ) {
		Add_Ammo( other, ent->item->giTag, quantity, qfalse );

		// Gordon: secondary weapon ammo
		if( ent->delay ) {
			Add_Ammo( other, weapAlts[ ent->item->giTag ], ent->delay, qfalse );
		}
	} else {
		if( level.time - other->client->dropWeaponTime < 1000 ) {
			return 0;
		}

		if( other->client->ps.weapon == WP_MORTAR_SET || other->client->ps.weapon == WP_MOBILE_MG42_SET ) {
			return 0;
		}

		// See if we can pick it up
		if( G_CanPickupWeapon( ent->item->giTag, other ) ) {
			weapon_t primaryWeapon = G_GetPrimaryWeaponForClient( other->client );

			// rain - added parens around ambiguous &&
			if( primaryWeapon || 
				(other->client->sess.playerType == PC_SOLDIER && other->client->sess.skill[SK_HEAVY_WEAPONS] >= 4) ) {

				if( primaryWeapon ) {
					// drop our primary weapon
					G_DropWeapon( other, primaryWeapon );
				}

				// now pickup the other one
				other->client->dropWeaponTime = level.time;

				// add the weapon
				COM_BitSet( other->client->ps.weapons, ent->item->giTag );

				// DHM - Fixup mauser/sniper issues
				if( ent->item->giTag == WP_FG42 ) {
					COM_BitSet( other->client->ps.weapons, WP_FG42SCOPE);
				} else if(ent->item->giTag == WP_GARAND) {
					COM_BitSet( other->client->ps.weapons, WP_GARAND_SCOPE);
				} else if( ent->item->giTag == WP_K43 ) {
					COM_BitSet( other->client->ps.weapons, WP_K43_SCOPE );
				} else if( ent->item->giTag == WP_MORTAR ) {
					COM_BitSet( other->client->ps.weapons, WP_MORTAR_SET );
				} else if( ent->item->giTag == WP_MOBILE_MG42 ) {
					COM_BitSet( other->client->ps.weapons, WP_MOBILE_MG42_SET );
				} else if( ent->item->giTag == WP_CARBINE ) {
					COM_BitSet( other->client->ps.weapons, WP_M7 );
				} else if( ent->item->giTag == WP_KAR98 ) {
					COM_BitSet( other->client->ps.weapons, WP_GPG40 );
				}

				other->client->ps.ammoclip[BG_FindClipForWeapon(ent->item->giTag)] = 0;
				other->client->ps.ammo[BG_FindAmmoForWeapon(ent->item->giTag)] = 0;

				if( ent->item->giTag == WP_MORTAR ) {
					other->client->ps.ammo[BG_FindClipForWeapon(ent->item->giTag)] = quantity;

					// Gordon: secondary weapon ammo
					if( ent->delay ) {
						Add_Ammo( other, weapAlts[ ent->item->giTag ], ent->delay, qfalse );
					}
				} else {
					other->client->ps.ammoclip[BG_FindClipForWeapon(ent->item->giTag)] = quantity;

					// Gordon: secondary weapon ammo
					if( ent->delay ) {
						other->client->ps.ammo[ weapAlts[ ent->item->giTag ] ] = ent->delay;
					}
				}
			}
		} else {
			return 0;
		}
	}

	// TAT 1/6/2003 - If we are a bot, call the pickup function
	if( other->r.svFlags & SVF_BOT )
		BotPickupWeapon( other->s.number, ent->item->giTag, alreadyHave );

	return -1;
}
예제 #5
0
void G_DropWeapon( gentity_t *ent, weapon_t weapon )
{
	vec3_t		angles, velocity, org, offset, mins, maxs;
	gclient_t	*client = ent->client;
	gentity_t	*ent2;
	gitem_t		*item;
	trace_t		tr;

	item = BG_FindItemForWeapon( weapon );
	VectorCopy( client->ps.viewangles, angles );

	// clamp pitch
	if ( angles[PITCH] < -30 )
		angles[PITCH] = -30;
	else if ( angles[PITCH] > 30 )
		angles[PITCH] = 30;

	AngleVectors( angles, velocity, NULL, NULL );
	VectorScale( velocity, 64, offset );
	offset[2] += client->ps.viewheight / 2.f;
	VectorScale( velocity, 75, velocity );
	velocity[2] += 50 + random() * 35;

	VectorAdd( client->ps.origin, offset, org );

	VectorSet( mins, -ITEM_RADIUS, -ITEM_RADIUS, 0 );
	VectorSet( maxs, ITEM_RADIUS, ITEM_RADIUS, 2*ITEM_RADIUS );

	trap_Trace( &tr, client->ps.origin, mins, maxs, org, ent->s.number, MASK_SOLID );
	VectorCopy( tr.endpos, org );

	ent2 = LaunchItem( item, org, velocity, client->ps.clientNum );
	COM_BitClear( client->ps.weapons, weapon );

	if( weapon == WP_KAR98 ) {
		COM_BitClear( client->ps.weapons, WP_GPG40 );
	} else if ( weapon == WP_CARBINE ) {
		COM_BitClear( client->ps.weapons, WP_M7 );
	} else if ( weapon == WP_FG42 ) {
		COM_BitClear( client->ps.weapons, WP_FG42SCOPE );
	} else if( weapon == WP_K43 ) {
		COM_BitClear( client->ps.weapons, WP_K43_SCOPE );
	} else if( weapon == WP_GARAND ) {
		COM_BitClear( client->ps.weapons, WP_GARAND_SCOPE );
	} else if( weapon == WP_MORTAR ) {
		COM_BitClear( client->ps.weapons, WP_MORTAR_SET );
	} else if( weapon == WP_MOBILE_MG42 ) {
		COM_BitClear( client->ps.weapons, WP_MOBILE_MG42_SET );
	}

	// Clear out empty weapon, change to next best weapon
	G_AddEvent( ent, EV_WEAPONSWITCHED, 0 );

	if( weapon == client->ps.weapon )
		client->ps.weapon = 0;

	if( weapon == WP_MORTAR ) {
		ent2->count = client->ps.ammo[BG_FindAmmoForWeapon(weapon)] + client->ps.ammoclip[BG_FindClipForWeapon(weapon)];
	} else {
		ent2->count = client->ps.ammoclip[BG_FindClipForWeapon(weapon)];
	}

	if( weapon == WP_KAR98 || weapon == WP_CARBINE ) {
		ent2->delay = client->ps.ammo[BG_FindAmmoForWeapon(weapAlts[weapon])];
	} else {
		ent2->delay = 0;
	}

//	ent2->item->quantity = client->ps.ammoclip[BG_FindClipForWeapon(weapon)]; // Gordon: um, modifying an item is not a good idea
	client->ps.ammoclip[BG_FindClipForWeapon(weapon)] = 0;
}
예제 #6
0
// TAT 11/6/2002
//		Local func to actual do skill upgrade, used by both MP skill system, and SP scripted skill system
static void G_UpgradeSkill( gentity_t *ent, skillType_t skill ) {
	int i, cnt = 0;

	// See if this is the first time we've reached this skill level
	for( i = 0; i < SK_NUM_SKILLS; i++ ) {
		if( i == skill )
			continue;

		if( ent->client->sess.skill[skill] <= ent->client->sess.skill[i] )
			break;
	}

	G_DebugAddSkillLevel( ent, skill );

	if( i == SK_NUM_SKILLS ) {
		// increase rank
		ent->client->sess.rank++;
	}

	if( ent->client->sess.rank >=4 ) {
		// Gordon: count the number of maxed out skills
		for( i = 0; i < SK_NUM_SKILLS; i++ ) {
			if( ent->client->sess.skill[ i ] >= 4 ) {
				cnt++;
			}
		}

		ent->client->sess.rank = cnt + 3;
		if( ent->client->sess.rank > 10 ) {
			ent->client->sess.rank = 10;
		}
	}

	ClientUserinfoChanged( ent-g_entities );

	// Give em rightaway
	if( skill == SK_BATTLE_SENSE && ent->client->sess.skill[skill] == 1 ) {
		if( AddWeaponToPlayer( ent->client, WP_BINOCULARS, 1, 0, qfalse ) ) {
			ent->client->ps.stats[STAT_KEYS] |= ( 1 << INV_BINOCS );
		}
	} else if( skill == SK_FIRST_AID && ent->client->sess.playerType == PC_MEDIC && ent->client->sess.skill[skill] == 4 ) {
		AddWeaponToPlayer( ent->client, WP_MEDIC_ADRENALINE, ent->client->ps.ammo[BG_FindAmmoForWeapon(WP_MEDIC_ADRENALINE)], ent->client->ps.ammoclip[BG_FindClipForWeapon(WP_MEDIC_ADRENALINE)], qfalse );
	}
}
예제 #7
0
파일: g_items.c 프로젝트: Justasic/RTCW-MP
int Pickup_Weapon( gentity_t *ent, gentity_t *other ) {
	int quantity;
	qboolean alreadyHave = qfalse;
	int i,weapon;         // JPW NERVE

// JPW NERVE -- magic ammo for any two-handed weapon
	if ( ent->item->giTag == WP_AMMO ) {
// if LT isn't giving ammo to self or another LT or the enemy, give him some props
		if ( other->client->ps.stats[STAT_PLAYER_CLASS] != PC_LT ) {
			if ( ent->parent ) {
				if ( other->client->sess.sessionTeam == ent->parent->client->sess.sessionTeam ) {
					if ( ent->parent->client ) {
						if ( !( ent->parent->client->PCSpecialPickedUpCount % LT_SPECIAL_PICKUP_MOD ) ) {
							AddScore( ent->parent, WOLF_AMMO_UP );
						}
						ent->parent->client->PCSpecialPickedUpCount++;
					}
				}
			}
		}

		// everybody likes grenades -- abuse weapon var as grenade type and i as max # grenades class can carry
		switch ( other->client->ps.stats[STAT_PLAYER_CLASS] ) {
		case PC_LT: // redundant but added for completeness/flexibility
		case PC_MEDIC:
			i = 1;
			break;
		case PC_SOLDIER:
			i = 4;
			break;
		case PC_ENGINEER:
			i = 8;
			break;
		default:
			i = 1;
			break;
		}
		if ( other->client->sess.sessionTeam == TEAM_RED ) {
			weapon = WP_GRENADE_LAUNCHER;
		} else {
			weapon = WP_GRENADE_PINEAPPLE;
		}
		if ( other->client->ps.ammoclip[BG_FindClipForWeapon( weapon )] < i ) {
			other->client->ps.ammoclip[BG_FindClipForWeapon( weapon )]++;
		}
		COM_BitSet( other->client->ps.weapons,weapon );

		// TTimo - add 8 pistol bullets
		if ( other->client->sess.sessionTeam == TEAM_RED ) {
			weapon = WP_LUGER;
		} else {
			weapon = WP_COLT;
		}
//		G_Printf("filling magazine for weapon %d colt/luger (%d rounds)\n", weapon, ammoTable[weapon].maxclip);
		other->client->ps.ammo[BG_FindAmmoForWeapon( weapon )] += ammoTable[weapon].maxclip;
		if ( other->client->ps.ammo[BG_FindAmmoForWeapon( weapon )] > ammoTable[weapon].maxclip * 4 ) {
			other->client->ps.ammo[BG_FindAmmoForWeapon( weapon )] = ammoTable[weapon].maxclip * 4;
		}

		// and some two-handed ammo
		for ( i = 0; i < MAX_WEAPS_IN_BANK_MP; i++ ) {
			weapon = weapBanksMultiPlayer[3][i];
			if ( COM_BitCheck( other->client->ps.weapons, weapon ) ) {
//				G_Printf("filling magazine for weapon %d (%d rounds)\n",weapon,ammoTable[weapon].maxclip);
				if ( weapon == WP_FLAMETHROWER ) { // FT doesn't use magazines so refill tank
					other->client->ps.ammoclip[BG_FindAmmoForWeapon( WP_FLAMETHROWER )] = ammoTable[weapon].maxclip;
				} else {
					other->client->ps.ammo[BG_FindAmmoForWeapon( weapon )] += ammoTable[weapon].maxclip;
					if ( other->client->ps.ammo[BG_FindAmmoForWeapon( weapon )] > ammoTable[weapon].maxclip * 3 ) {
						other->client->ps.ammo[BG_FindAmmoForWeapon( weapon )] = ammoTable[weapon].maxclip * 3;
					}
				}
				return RESPAWN_SP;
			}
		}
		return RESPAWN_SP;
	}
// jpw
	if ( ent->count < 0 ) {
		quantity = 0; // None for you, sir!
	} else {
		if ( ent->count ) {
			quantity = ent->count;
		} else {
//----(SA) modified
// JPW NERVE did this so ammocounts work right on dropped weapons
			if ( g_gametype.integer != GT_SINGLE_PLAYER ) {
				quantity = ent->item->quantity;
			} else {
// jpw
				quantity = ( random() * ( ent->item->quantity - 1 ) ) + 1;  // giving 1-<item default count>
			}
		}
	}

	// check if player already had the weapon
	alreadyHave = COM_BitCheck( other->client->ps.weapons, ent->item->giTag );

	// add the weapon
	COM_BitSet( other->client->ps.weapons, ent->item->giTag );

	// DHM - Fixup mauser/sniper issues
	if ( ent->item->giTag == WP_MAUSER ) {
		COM_BitSet( other->client->ps.weapons, WP_SNIPERRIFLE );
	}
	if ( ent->item->giTag == WP_SNIPERRIFLE ) {
		COM_BitSet( other->client->ps.weapons, WP_MAUSER );
	}

	//----(SA)	added
	// snooper == automatic garand mod
	if ( ent->item->giTag == WP_SNOOPERSCOPE ) {
		COM_BitSet( other->client->ps.weapons, WP_GARAND );
	}
	// fg42scope == automatic fg42 mod
	else if ( ent->item->giTag == WP_FG42SCOPE ) {
		COM_BitSet( other->client->ps.weapons, WP_FG42 );
	} else if ( ent->item->giTag == WP_GARAND ) {
		COM_BitSet( other->client->ps.weapons, WP_SNOOPERSCOPE );
	}
	//----(SA)	end

// JPW NERVE  prevents drop/pickup weapon "quick reload" exploit
	if ( alreadyHave ) {
		Add_Ammo( other, ent->item->giTag, quantity, !alreadyHave );
	} else {
		other->client->ps.ammoclip[BG_FindClipForWeapon( ent->item->giTag )] = quantity;
	}
// jpw

	// single player has no respawns	(SA)
	if ( g_gametype.integer == GT_SINGLE_PLAYER ) {
		return RESPAWN_SP;
	}

	if ( g_gametype.integer == GT_TEAM ) {
		return g_weaponTeamRespawn.integer;
	}

	return g_weaponRespawn.integer;
}
예제 #8
0
static int CG_PlayerAmmoValue(int *ammo, int *clips, int *akimboammo)
{
	centity_t     *cent;
	playerState_t *ps;
	int           weap;
	qboolean      skipammo = qfalse;

	*ammo = *clips = *akimboammo = -1;

	if (cg.snap->ps.clientNum == cg.clientNum)
	{
		cent = &cg.predictedPlayerEntity;
	}
	else
	{
		cent = &cg_entities[cg.snap->ps.clientNum];
	}
	ps = &cg.snap->ps;

	weap = cent->currentState.weapon;

	if (!weap)
	{
		return weap;
	}

	switch (weap)          // some weapons don't draw ammo count text
	{
	case WP_AMMO:
	case WP_MEDKIT:
	case WP_KNIFE:
	case WP_PLIERS:
	case WP_SMOKE_MARKER:
	case WP_DYNAMITE:
	case WP_SATCHEL:
	case WP_SATCHEL_DET:
	case WP_SMOKE_BOMB:
	case WP_BINOCULARS:
		return weap;

	case WP_LANDMINE:
	case WP_MEDIC_SYRINGE:
	case WP_MEDIC_ADRENALINE:
	case WP_GRENADE_LAUNCHER:
	case WP_GRENADE_PINEAPPLE:
	case WP_FLAMETHROWER:
	case WP_MORTAR:
	case WP_MORTAR_SET:
	case WP_PANZERFAUST:
		skipammo = qtrue;
		break;

	default:
		break;
	}

	if (cg.snap->ps.eFlags & EF_MG42_ACTIVE || cg.snap->ps.eFlags & EF_MOUNTEDTANK)
	{
		return WP_MOBILE_MG42;
	}

	// total ammo in clips
	*clips = cg.snap->ps.ammo[BG_FindAmmoForWeapon(weap)];

	// current clip
	*ammo = ps->ammoclip[BG_FindClipForWeapon(weap)];

	if (BG_IsAkimboWeapon(weap))
	{
		*akimboammo = ps->ammoclip[BG_FindClipForWeapon(BG_AkimboSidearm(weap))];
	}
	else
	{
		*akimboammo = -1;
	}

	if (weap == WP_LANDMINE)
	{
		if (!cgs.gameManager)
		{
			*ammo = 0;
		}
		else
		{
			if (cgs.clientinfo[ps->clientNum].team == TEAM_AXIS)
			{
				*ammo = cgs.gameManager->currentState.otherEntityNum;
			}
			else
			{
				*ammo = cgs.gameManager->currentState.otherEntityNum2;
			}
		}
	}
	else if (weap == WP_MORTAR || weap == WP_MORTAR_SET || weap == WP_PANZERFAUST)
	{
		*ammo += *clips;
	}

	if (skipammo)
	{
		*clips = -1;
	}

	return weap;
}