static void PortalTouch(gentity_t * self, gentity_t * other, trace_t * trace) { gentity_t *destination; // see if we will even let other try to use it if(other->health <= 0) { return; } if(!other->client) { return; } // if( other->client->ps.persistant[PERS_TEAM] != self->spawnflags ) { // return; // } if(other->client->ps.powerups[PW_NEUTRALFLAG]) { // only happens in One Flag CTF Drop_Item(other, BG_FindItemForPowerup(PW_NEUTRALFLAG), 0); other->client->ps.powerups[PW_NEUTRALFLAG] = 0; } else if(other->client->ps.powerups[PW_REDFLAG]) { // only happens in standard CTF Drop_Item(other, BG_FindItemForPowerup(PW_REDFLAG), 0); other->client->ps.powerups[PW_REDFLAG] = 0; } else if(other->client->ps.powerups[PW_BLUEFLAG]) { // only happens in standard CTF Drop_Item(other, BG_FindItemForPowerup(PW_BLUEFLAG), 0); other->client->ps.powerups[PW_BLUEFLAG] = 0; } // find the destination destination = NULL; while((destination = G_Find(destination, FOFS(classname), "hi_portal destination")) != NULL) { if(destination->count == self->count) { break; } } // if there is not one, die! if(!destination) { if(self->pos1[0] || self->pos1[1] || self->pos1[2]) { TeleportPlayer(other, self->pos1, self->s.angles); } G_Damage(other, other, other, NULL, NULL, 100000, DAMAGE_NO_PROTECTION, MOD_TELEFRAG); return; } TeleportPlayer(other, destination->s.pos.trBase, destination->s.angles); }
/* =========== TossPlayerGametypeItems Drop CTF flag and Harvester cubes =========== */ void TossPlayerGametypeItems(gentity_t *ent) { int j; gitem_t *item; gentity_t *drop; int angle = 0; // drop flags in CTF item = NULL; j = 0; if ( ent->player->ps.powerups[ PW_REDFLAG ] ) { item = BG_FindItemForPowerup( PW_REDFLAG ); j = PW_REDFLAG; } else if ( ent->player->ps.powerups[ PW_BLUEFLAG ] ) { item = BG_FindItemForPowerup( PW_BLUEFLAG ); j = PW_BLUEFLAG; } else if ( ent->player->ps.powerups[ PW_NEUTRALFLAG ] ) { item = BG_FindItemForPowerup( PW_NEUTRALFLAG ); j = PW_NEUTRALFLAG; } if ( item ) { drop = Drop_Item( ent, item, angle ); angle += 45; // decide how many seconds it has left drop->count = ( ent->player->ps.powerups[ j ] - level.time ) / 1000; if ( drop->count < 1 ) { drop->count = 1; } ent->player->ps.powerups[ j ] = 0; } #ifdef MISSIONPACK if ( g_gametype.integer == GT_HARVESTER ) { if ( ent->player->ps.tokens > 0 ) { if ( ent->player->sess.sessionTeam == TEAM_RED ) { item = BG_FindItem( "Blue Cube" ); } else { item = BG_FindItem( "Red Cube" ); } if ( item ) { for ( j = 0; j < ent->player->ps.tokens; j++ ) { drop = Drop_Item( ent, item, angle ); if ( ent->player->sess.sessionTeam == TEAM_RED ) { drop->s.team = TEAM_BLUE; } else { drop->s.team = TEAM_RED; } angle += 45; } } ent->player->ps.tokens = 0; } } #endif }
/* ================ CG_DrawFlagModel Used for both the status bar and the scoreboard ================ */ void CG_DrawFlagModel( float x, float y, float w, float h, int team, qboolean force2D ) { qhandle_t cm; float len; vec3_t origin, angles; vec3_t mins, maxs; qhandle_t handle; if ( !force2D && cg_draw3dIcons.integer ) { VectorClear( angles ); cm = cgs.media.redFlagModel; // offset the origin y and z to center the flag trap_R_ModelBounds( cm, mins, maxs ); origin[2] = -0.5 * ( mins[2] + maxs[2] ); origin[1] = 0.5 * ( mins[1] + maxs[1] ); // calculate distance so the flag nearly fills the box // assume heads are taller than wide len = 0.5 * ( maxs[2] - mins[2] ); origin[0] = len / 0.268; // len / tan( fov/2 ) angles[YAW] = 60 * sin( (cg.time / 2000.0) + cg.timeFraction / 2000.0 );; if( team == TEAM_RED ) { handle = cgs.media.redFlagModel; } else if( team == TEAM_BLUE ) { handle = cgs.media.blueFlagModel; } else if( team == TEAM_FREE ) { handle = cgs.media.neutralFlagModel; } else { return; } CG_Draw3DModel( x, y, w, h, handle, 0, origin, angles ); } else if ( cg_drawIcons.integer ) { gitem_t *item; if( team == TEAM_RED ) { item = BG_FindItemForPowerup( PW_REDFLAG ); } else if( team == TEAM_BLUE ) { item = BG_FindItemForPowerup( PW_BLUEFLAG ); } else if( team == TEAM_FREE ) { item = BG_FindItemForPowerup( PW_NEUTRALFLAG ); } else { return; } if (item) { CG_DrawPic( x, y, w, h, cg_items[ ITEM_INDEX(item) ].icon ); } } }
/* ================= TossClientItems Toss the weapon and powerups for the killed player ================= */ void TossClientItems( gentity_t *self ) { gitem_t *item; int weapon; float angle; int i; gentity_t *drop; // drop the weapon if not a gauntlet or machinegun weapon = self->s.weapon; //Never drop in elimination or last man standing mode! if( g_gametype.integer == GT_ELIMINATION || g_gametype.integer == GT_LMS) return; // make a special check to see if they are changing to a new // weapon that isn't the mg or gauntlet. Without this, a client // can pick up a weapon, be killed, and not drop the weapon because // their weapon change hasn't completed yet and they are still holding the MG. if ( weapon == WP_MACHINEGUN || weapon == WP_GRAPPLING_HOOK ) { if ( self->client->ps.weaponstate == WEAPON_DROPPING ) { weapon = self->client->pers.cmd.weapon; } if ( !( self->client->ps.stats[STAT_WEAPONS] & ( 1 << weapon ) ) ) { weapon = WP_NONE; } } if (g_instantgib.integer || g_rockets.integer || g_gametype.integer == GT_CTF_ELIMINATION || g_elimination_allgametypes.integer){ //Nothing! } else if ( weapon > WP_MACHINEGUN && weapon != WP_GRAPPLING_HOOK && self->client->ps.ammo[ weapon ] ) { // find the item type for this weapon item = BG_FindItemForWeapon( weapon ); // spawn the item Drop_Item( self, item, 0 ); } // drop all the powerups if not in teamplay if ( g_gametype.integer != GT_TEAM ) { angle = 45; for ( i = 1 ; i < PW_NUM_POWERUPS ; i++ ) { if ( self->client->ps.powerups[ i ] > level.time ) { item = BG_FindItemForPowerup( i ); if ( !item ) { continue; } drop = Drop_Item( self, item, angle ); // decide how many seconds it has left drop->count = ( self->client->ps.powerups[ i ] - level.time ) / 1000; if ( drop->count < 1 ) { drop->count = 1; } angle += 45; } } } }
/* ================ CG_DrawFlagModel Used for both the status bar and the scoreboard JKGFIXME: use an icon instead bro, this is so 1999 --eez ================ */ void CG_DrawFlagModel( float x, float y, float w, float h, int team, qboolean force2D ) { if ( cg_drawIcons.integer ) { gitem_t *item; if( team == TEAM_RED ) { item = BG_FindItemForPowerup( PW_REDFLAG ); } else if( team == TEAM_BLUE ) { item = BG_FindItemForPowerup( PW_BLUEFLAG ); } else { return; } if (item) { CG_DrawPic( x, y, w, h, cg_items[ ITEM_INDEX(item) ].icon ); } } }
/* ================= TossPlayerItems Toss the weapon and powerups for the killed player ================= */ void TossPlayerItems( gentity_t *self ) { gitem_t *item; int weapon; float angle; int i; gentity_t *drop; // drop the weapon if not a gauntlet or machinegun weapon = self->s.weapon; // make a special check to see if they are changing to a new // weapon that isn't the mg or gauntlet. Without this, a player // can pick up a weapon, be killed, and not drop the weapon because // their weapon change hasn't completed yet and they are still holding the MG. if ( weapon == WP_MACHINEGUN || weapon == WP_GRAPPLING_HOOK ) { if ( self->player->ps.weaponstate == WEAPON_DROPPING ) { BG_DecomposeUserCmdValue( self->player->pers.cmd.stateValue, &weapon ); } if ( !( self->player->ps.stats[STAT_WEAPONS] & ( 1 << weapon ) ) ) { weapon = WP_NONE; } } if ( weapon > WP_MACHINEGUN && weapon != WP_GRAPPLING_HOOK && self->player->ps.ammo[ weapon ] ) { // find the item type for this weapon item = BG_FindItemForWeapon( weapon ); // spawn the item Drop_Item( self, item, 0 ); } // drop all the powerups if not in teamplay if ( g_gametype.integer != GT_TEAM ) { angle = 45; for ( i = 1 ; i < PW_NUM_POWERUPS ; i++ ) { if ( self->player->ps.powerups[ i ] > level.time ) { item = BG_FindItemForPowerup( i ); if ( !item ) { continue; } drop = Drop_Item( self, item, angle ); // decide how many seconds it has left drop->count = ( self->player->ps.powerups[ i ] - level.time ) / 1000; if ( drop->count < 1 ) { drop->count = 1; } angle += 45; } } } }
void ThinkNoSlow( gentity_t *self ) { gitem_t *item = NULL; gentity_t *dropped = NULL; item = BG_FindItemForPowerup( self->powerupModelType ); if(!item) { G_Printf("Error: couldn't find powerup.\n"); return; } self->child = DropPowerup(self, item, TouchPowerupNoSlow, qfalse); }
void ThinkSlick( gentity_t *self ) { gitem_t *item = NULL; gentity_t *dropped = NULL; // FIXME: wrong PW_ item = BG_FindItemForPowerup( self->powerupModelType ); if(!item) { G_Printf("Error: couldn't find powerup.\n"); return; } self->child = DropPowerup(self, item, TouchPowerupSlick, qfalse); }
void think_random( gentity_t *self ) { gitem_t *item = NULL; gentity_t *dropped = NULL; int i = rand() % numPowerups; // FIXME: wrong PW_ item = BG_FindItemForPowerup( PW_RANDOM ); if(!item) { G_Printf("Error: couldn't find powerup model.\n"); return; } self->child = DropPowerup(self, item, powerups[i].touch, qfalse); }
static void CG_DrawRedFlagStatus(rectDef_t *rect, qhandle_t shader) { if (cgs.gametype != GT_FLAGS && cgs.gametype != GT_TROJAN) { return; } if (shader) { CG_DrawPic( rect->x, rect->y, rect->w, rect->h, shader ); } else { const gitem_t *item = BG_FindItemForPowerup( PW_REDFLAG ); if (item) { vector4 color = {1, 0, 0, 1}; trap->R_SetColor(&color); if( cgs.redflag >= 0 && cgs.redflag <= 2) { CG_DrawPic( rect->x, rect->y, rect->w, rect->h, cgs.media.flagShaders[cgs.redflag] ); } else { CG_DrawPic( rect->x, rect->y, rect->w, rect->h, cgs.media.flagShaders[0] ); } trap->R_SetColor(NULL); } } }
static void CG_OneFlagStatus(rectDef_t *rect) { if (cgs.gametype != GT_TROJAN) { return; } else { const gitem_t *item = BG_FindItemForPowerup( PW_NEUTRALFLAG ); if (item) { if( cgs.flagStatus >= 0 && cgs.flagStatus <= 4 ) { vector4 color = {1, 1, 1, 1}; int index = 0; if (cgs.flagStatus == FLAG_TAKEN_RED) { color.g = color.b = 0; index = 1; } else if (cgs.flagStatus == FLAG_TAKEN_BLUE) { color.r = color.g = 0; index = 1; } else if (cgs.flagStatus == FLAG_DROPPED) { index = 2; } trap->R_SetColor(&color); CG_DrawPic( rect->x, rect->y, rect->w, rect->h, cgs.media.flagShaders[index] ); } } } }
/* ================ ClientEvents Events will be passed on to the clients for presentation, but any server game effects are handled here ================ */ void ClientEvents(gentity_t * ent, int oldEventSequence) { int i, j; int event; gclient_t *client; int damage; // vec3_t dir; vec3_t origin, angles; gitem_t *item; gentity_t *drop; client = ent->client; if (oldEventSequence < client->ps.eventSequence - MAX_PS_EVENTS) { oldEventSequence = client->ps.eventSequence - MAX_PS_EVENTS; } for (i = oldEventSequence; i < client->ps.eventSequence; i++) { event = client->ps.events[i & (MAX_PS_EVENTS - 1)]; switch (event) { case EV_FALL_MEDIUM: case EV_FALL_FAR: if (ent->s.eType != ET_PLAYER) { break; // not in the player model } if (g_dmflags.integer & DF_NO_FALLING) { break; } // JBravo: fix falling pain during lca if (g_gametype.integer >= GT_TEAM && level.lights_camera_action) { break; } damage = ent->client->ps.stats[STAT_FALLDAMAGE]; // VectorSet(dir, 0, 0, 1); ent->pain_debounce_time = level.time + 200; // no normal pain sound //Elder: added so we can trigger AQ2 pain blends ent->client->ps.damageEvent++; ent->client->ps.damageCount += damage; if (ent->client->lasthurt_mod != 0) { //Blaze: Print out some debug info if (&g_entities[ent->client->lasthurt_client] == NULL) G_Printf("Ln 0748\n"); G_Damage(ent, &g_entities[ent->client->lasthurt_client], &g_entities[ent->client->lasthurt_client], NULL, NULL, damage, 0, MOD_FALLING); } else { G_Damage(ent, NULL, NULL, NULL, NULL, damage, 0, MOD_FALLING); } break; case EV_FALL_FAR_NOSOUND: if (ent->s.eType != ET_PLAYER) { break; // not in the player model } if (g_dmflags.integer & DF_NO_FALLING) { break; } // JBravo: fix falling pain during lca again if (g_gametype.integer >= GT_TEAM && level.lights_camera_action) { break; } damage = ent->client->ps.stats[STAT_FALLDAMAGE]; // VectorSet(dir, 0, 0, 1); ent->pain_debounce_time = level.time + 200; // no normal pain sound //Elder: added so we can trigger AQ2 pain blends ent->client->ps.damageEvent++; ent->client->ps.damageCount += damage; if (ent->client->lasthurt_mod != 0) { //Blaze: Print out some debug info if (&g_entities[ent->client->lasthurt_client] == NULL) G_Printf("Ln 0779\n"); G_Damage(ent, &g_entities[ent->client->lasthurt_client], &g_entities[ent->client->lasthurt_client], NULL, NULL, damage, 0, MOD_FALLING); } else { G_Damage(ent, NULL, NULL, NULL, NULL, damage, 0, MOD_FALLING); } break; case EV_FIRE_WEAPON: FireWeapon(ent); break; case EV_RELOAD_WEAPON1: ReloadWeapon(ent, 1); break; case EV_RELOAD_WEAPON2: ReloadWeapon(ent, 2); break; case EV_CHANGE_WEAPON: //Elder: not a good place to put stuff break; case EV_USE_ITEM1: // teleporter // drop flags in CTF item = NULL; j = 0; if (ent->client->ps.powerups[PW_REDFLAG]) { item = BG_FindItemForPowerup(PW_REDFLAG); j = PW_REDFLAG; } else if (ent->client->ps.powerups[PW_BLUEFLAG]) { item = BG_FindItemForPowerup(PW_BLUEFLAG); j = PW_BLUEFLAG; } else if (ent->client->ps.powerups[PW_NEUTRALFLAG]) { item = BG_FindItemForPowerup(PW_NEUTRALFLAG); j = PW_NEUTRALFLAG; } if (item) { drop = Drop_Item(ent, item, 0); // decide how many seconds it has left drop->count = (ent->client->ps.powerups[j] - level.time) / 1000; if (drop->count < 1) { drop->count = 1; } ent->client->ps.powerups[j] = 0; } SelectSpawnPoint(ent->client->ps.origin, origin, angles); TeleportPlayer(ent, origin, angles); break; case EV_USE_ITEM2: // medkit ent->health = 125; //ent->client->ps.stats[STAT_MAX_HEALTH] + 25; break; default: break; } } }
void CG_DrawNewTeamInfo(rectDef_t *rect, float text_x, float text_y, float scale, vector4 *color, qhandle_t shader) { int i, j, count, xx; const char *p; vector4 hcolor; float pwidth, lwidth, maxx, leftOver, len, y; clientInfo_t *ci; const gitem_t *item; // max player name width pwidth = 0; count = (numSortedTeamPlayers > 8) ? 8 : numSortedTeamPlayers; for (i = 0; i < count; i++) { ci = cgs.clientinfo + sortedTeamPlayers[i]; if ( ci->infoValid && ci->team == cg.snap->ps.persistent[PERS_TEAM]) { len = CG_Text_Width( ci->name, scale, 0); if (len > pwidth) pwidth = (float)len; } } // max location name width lwidth = 0; for (i = 1; i < MAX_LOCATIONS; i++) { p = CG_ConfigString(CS_LOCATIONS + i); if (p && *p) { len = CG_Text_Width(p, scale, 0); if (len > lwidth) lwidth = (float)len; } } y = rect->y; for (i = 0; i < count; i++) { ci = cgs.clientinfo + sortedTeamPlayers[i]; if ( ci->infoValid && ci->team == cg.snap->ps.persistent[PERS_TEAM]) { xx = (int)rect->x + 1; for (j = 0; j <= PW_NUM_POWERUPS; j++) { if (ci->powerups & (1 << j)) { item = BG_FindItemForPowerup( j ); if (item) { CG_DrawPic( (float)xx, y, PIC_WIDTH, PIC_WIDTH, trap->R_RegisterShader( item->icon ) ); xx += PIC_WIDTH; } } } // FIXME: max of 3 powerups shown properly xx = (int)rect->x + (PIC_WIDTH * 3) + 2; CG_GetColorForHealth( ci->health, ci->armor, &hcolor ); trap->R_SetColor(&hcolor); CG_DrawPic( (float)xx, y + 1, PIC_WIDTH - 2, PIC_WIDTH - 2, cgs.media.heartShader ); //Com_sprintf (st, sizeof(st), "%3i %3i", ci->health, ci->armor); //CG_Text_Paint(xx, y + text_y, scale, hcolor, st, 0, 0); // draw weapon icon xx += PIC_WIDTH + 1; // weapon used is not that useful, use the space for task #if 0 if ( cg_weapons[ci->curWeapon].weaponIcon ) { CG_DrawPic( xx, y, PIC_WIDTH, PIC_WIDTH, cg_weapons[ci->curWeapon].weaponIcon ); } else { CG_DrawPic( xx, y, PIC_WIDTH, PIC_WIDTH, cgs.media.deferShader ); } #endif trap->R_SetColor(NULL); leftOver = rect->w - xx; maxx = xx + leftOver / 3; CG_Text_Paint_Limit(&maxx, (float)xx, y + text_y, scale, color, ci->name, 0, 0); p = CG_ConfigString(CS_LOCATIONS + ci->location); if (!p || !*p) { p = "unknown"; } xx += (int)(leftOver/3 + 2); maxx = rect->w - 4; CG_Text_Paint_Limit(&maxx, (float)xx, y + text_y, scale, color, p, 0, 0); y += text_y + 2; if ( y + text_y + 2 > rect->y + rect->h ) { break; } } } }
static void CG_DrawAreaPowerUp(rectDef_t *rect, int align, float special, float scale, vector4 *color) { char num[16]; int sorted[MAX_POWERUPS], sortedTime[MAX_POWERUPS]; int i, j, k, t, active; float f, *inc; playerState_t *ps; const gitem_t *item; rectDef_t r2; r2.x = rect->x; r2.y = rect->y; r2.w = rect->w; r2.h = rect->h; inc = (align == HUD_VERTICAL) ? &r2.y : &r2.x; ps = &cg.snap->ps; if ( ps->stats[STAT_HEALTH] <= 0 ) { return; } // sort the list by time remaining active = 0; for ( i = 0 ; i < MAX_POWERUPS ; i++ ) { if ( !ps->powerups[ i ] ) { continue; } t = ps->powerups[ i ] - cg.time; // ZOID--don't draw if the power up has unlimited time (999 seconds) // This is true of the CTF flags if ( t <= 0 || t >= 999000) { continue; } // insert into the list for ( j = 0 ; j < active ; j++ ) { if ( sortedTime[j] >= t ) { for ( k = active - 1 ; k >= j ; k-- ) { sorted[k+1] = sorted[k]; sortedTime[k+1] = sortedTime[k]; } break; } } sorted[j] = i; sortedTime[j] = t; active++; } // draw the icons and timers for ( i = 0 ; i < active ; i++ ) { item = BG_FindItemForPowerup( sorted[i] ); if (item) { t = ps->powerups[ sorted[i] ]; if ( t - cg.time >= POWERUP_BLINKS * POWERUP_BLINK_TIME ) { trap->R_SetColor( NULL ); } else { vector4 modulate; f = (float)( t - cg.time ) / POWERUP_BLINK_TIME; f -= (int)f; modulate.r = modulate.g = modulate.b = modulate.a = f; trap->R_SetColor( &modulate ); } CG_DrawPic( r2.x, r2.y, r2.w * .75f, r2.h, trap->R_RegisterShader( item->icon ) ); Com_sprintf (num, sizeof(num), "%i", sortedTime[i] / 1000); CG_Text_Paint(r2.x + (r2.w * .75f) + 3 , r2.y + r2.h, scale, color, num, 0, 0, 0); *inc += r2.w + special; } } trap->R_SetColor( NULL ); }
static void Cmd_Drop_f( gentity_t *ent ) { char arg[128] = {0}; trap->Cmd_Argv( 1, arg, sizeof( arg ) ); if ( !Q_stricmp( arg, "flag" ) ) { powerup_t powerup = (ent->client->ps.persistent[PERS_TEAM]==TEAM_RED) ? PW_BLUEFLAG : PW_REDFLAG; if ( !g_allowFlagDrop->integer ) { trap->SV_GameSendServerCommand( ARRAY_INDEX( g_entities, ent ), "print \"^3Not allowed to drop the flag\n\"" ); return; } if ( level.gametype != GT_FLAGS || (ent->client->ps.powerups[powerup] <= level.time) ) { trap->SV_GameSendServerCommand( ARRAY_INDEX( g_entities, ent ), "print \"^3No flag to drop\n\"" ); return; } if ( ent->client->ps.powerups[ powerup ] > level.time ) { const gitem_t *item = BG_FindItemForPowerup( powerup ); gentity_t *drop = NULL; vector3 angs = { 0.0f, 0.0f, 0.0f }; AngleVectors( &ent->client->ps.viewangles, &angs, NULL, NULL ); drop = Drop_Item( ent, item, angs.yaw ); //Raz: speed caps drop->genericValue1 = trap->Milliseconds() - (int)ent->client->pers.teamState.flagsince; // drop->genericValue2 = ARRAY_INDEX( g_entities, ent ); // drop->genericValue2 |= (1<<5); // 6th bit indicates a client dropped it on purpose // drop->genericValue2 |= level.time << 6; ent->client->ps.powerups[powerup] = 0; } } else if ( !Q_stricmp( arg, "weapon" ) ) { weapon_t wp = (weapon_t)ent->client->ps.weapon, newWeap = -1; const gitem_t *item = NULL; gentity_t *drop = NULL; vector3 angs = { 0.0f, 0.0f, 0.0f }; int ammo, i=0; if ( !g_allowWeaponDrop->integer ) { trap->SV_GameSendServerCommand( ARRAY_INDEX( g_entities, ent ), "print \"^3Not allowed to drop weapons\n\"" ); return; } if ( !(ent->client->ps.stats[STAT_WEAPONS] & (1<<wp)) || !ent->client->ps.ammo[wp] || wp == WP_QUANTIZER || wp <= WP_NONE || wp > WP_NUM_WEAPONS ) {// We don't have this weapon or ammo for it, or it's a 'weapon' that can't be dropped trap->SV_GameSendServerCommand( ARRAY_INDEX( g_entities, ent ), "print \"^3Can't drop this weapon\n\"" ); return; } item = BG_FindItemForWeapon( wp ); if ( !ent->client->ps.ammo[wp] ) { trap->SV_GameSendServerCommand( ARRAY_INDEX( g_entities, ent ), "print \"^3No ammo for this weapon\n\"" ); return; } else if ( ent->client->ps.ammo[wp] > item->quantity ) ammo = item->quantity; else ammo = ent->client->ps.ammo[wp]; AngleVectors( &ent->client->ps.viewangles, &angs, NULL, NULL ); drop = Drop_Item( ent, item, angs.yaw ); drop->count = ammo; ent->client->ps.ammo[wp] -= ammo; ent->client->ps.stats[STAT_WEAPONS] &= ~(1<<wp); #if 1 for ( i=0; i<WP_NUM_WEAPONS; i++ ) { if ((ent->client->ps.stats[STAT_WEAPONS] & (1 << i)) && i != WP_NONE) { //this one's good newWeap = (weapon_t)i; break; } } if (newWeap != -1) { ent->s.weapon = newWeap; ent->client->ps.weapon = newWeap; } else { ent->s.weapon = 0; ent->client->ps.weapon = 0; } G_AddEvent( ent, EV_NOAMMO, wp ); #else for ( i=wp+1; i != wp-1; i++ ) { if ( i == WP_NUM_WEAPONS ) i = WP_NONE+1; if ( ent->client->ps.stats[STAT_WEAPONS] & (1<<i) ) { ent->client->ps.weapon = i; break; } } G_AddEvent( ent, EV_NOAMMO, wp ); #endif drop->genericValue2 = ARRAY_INDEX( g_entities, ent ); drop->genericValue2 |= (1<<5); // 6th bit indicates a client dropped it on purpose drop->genericValue2 |= level.time << 6; } else if ( !Q_stricmp( arg, "powerup" ) ) { //RAZTODO: /drop powerup return; } }
/* ================= TossClientItems Toss the weapon and powerups for the killed player ================= */ void TossClientItems( gentity_t *self ) { gitem_t *item; vec3_t forward; int weapon; float angle; int i; gentity_t *drop = 0; // drop the weapon if not a gauntlet or machinegun weapon = self->s.weapon; switch ( self->aiCharacter ) { case AICHAR_ZOMBIE: case AICHAR_WARZOMBIE: case AICHAR_LOPER: return; //----(SA) removed DK's special case default: break; } AngleVectors( self->r.currentAngles, forward, NULL, NULL ); G_ThrowChair( self, forward, qtrue ); // drop chair if you're holding one //----(SA) added // make a special check to see if they are changing to a new // weapon that isn't the mg or gauntlet. Without this, a client // can pick up a weapon, be killed, and not drop the weapon because // their weapon change hasn't completed yet and they are still holding the MG. // (SA) always drop what you were switching to if ( 1 ) { // if ( weapon == WP_MACHINEGUN || weapon == WP_GRAPPLING_HOOK ) { if ( self->client->ps.weaponstate == WEAPON_DROPPING || self->client->ps.weaponstate == WEAPON_DROPPING_TORELOAD ) { weapon = self->client->pers.cmd.weapon; } if ( !( COM_BitCheck( self->client->ps.weapons, weapon ) ) ) { weapon = WP_NONE; } } //----(SA) added if ( weapon == WP_SNOOPERSCOPE ) { weapon = WP_GARAND; } if ( weapon == WP_FG42SCOPE ) { weapon = WP_FG42; } if ( weapon == WP_AKIMBO ) { //----(SA) added weapon = WP_COLT; } //----(SA) end if ( weapon > WP_NONE && weapon < WP_MONSTER_ATTACK1 && self->client->ps.ammo[ BG_FindAmmoForWeapon( weapon )] ) { // find the item type for this weapon item = BG_FindItemForWeapon( weapon ); // spawn the item // Rafael if ( !( self->client->ps.persistant[PERS_HWEAPON_USE] ) ) { drop = Drop_Item( self, item, 0, qfalse ); } } if ( g_gametype.integer == GT_SINGLE_PLAYER ) { // dropped items stay forever in SP if ( drop ) { drop->nextthink = 0; } } if ( g_gametype.integer != GT_TEAM ) { // drop all the powerups if not in teamplay angle = 45; for ( i = 1 ; i < PW_NUM_POWERUPS ; i++ ) { if ( self->client->ps.powerups[ i ] > level.time ) { item = BG_FindItemForPowerup( i ); if ( !item ) { continue; } drop = Drop_Item( self, item, angle, qfalse ); // decide how many seconds it has left drop->count = ( self->client->ps.powerups[ i ] - level.time ) / 1000; if ( drop->count < 1 ) { drop->count = 1; } drop->nextthink = 0; // stay forever angle += 45; } } } }