/* ------------------------- NPC_Mark1_Precache ------------------------- */ void NPC_Mark1_Precache(void) { G_SoundIndex( "sound/chars/mark1/misc/mark1_wakeup"); G_SoundIndex( "sound/chars/mark1/misc/shutdown"); G_SoundIndex( "sound/chars/mark1/misc/walk"); G_SoundIndex( "sound/chars/mark1/misc/run"); G_SoundIndex( "sound/chars/mark1/misc/death1"); G_SoundIndex( "sound/chars/mark1/misc/death2"); G_SoundIndex( "sound/chars/mark1/misc/anger"); G_SoundIndex( "sound/chars/mark1/misc/mark1_fire"); G_SoundIndex( "sound/chars/mark1/misc/mark1_pain"); G_SoundIndex( "sound/chars/mark1/misc/mark1_explo"); // G_EffectIndex( "small_chunks"); G_EffectIndex( "env/med_explode2"); G_EffectIndex( "explosions/probeexplosion1"); G_EffectIndex( "blaster/smoke_bolton"); G_EffectIndex( "bryar/muzzle_flash"); G_EffectIndex( "explosions/droidexplosion1" ); RegisterItem( BG_FindItemForAmmo( AMMO_METAL_BOLTS)); RegisterItem( BG_FindItemForAmmo( AMMO_BLASTER )); RegisterItem( BG_FindItemForWeapon( WP_BOWCASTER )); RegisterItem( BG_FindItemForWeapon( WP_BRYAR_PISTOL )); }
/* ============== ClearRegisteredItems ============== */ void ClearRegisteredItems( void ) { memset( itemRegistered, 0, sizeof( itemRegistered ) ); // players always start with the base weapon RegisterItem( BG_FindItemForWeapon( WP_PISTOL ) ); RegisterItem( BG_FindItemForWeapon( WP_GAUNTLET ) ); RegisterItem( BG_FindItem("Bag 'O Money" ) ); RegisterItem( BG_FindItem("Hidden Stash" ) ); }
/* ============== ClearRegisteredItems ============== */ void ClearRegisteredItems(void) { memset(itemRegistered, 0, sizeof(itemRegistered)); // players always start with the base weapon //Blaze: Changed WP_MACHINEGUN to WP_PISTOL and WP_GAUNTLET to WP_KNIFE RegisterItem(BG_FindItemForWeapon(WP_PISTOL)); RegisterItem(BG_FindItemForWeapon(WP_KNIFE)); //Elder: add unique items here RegisterItem(BG_FindItemForHoldable(HI_KEVLAR)); RegisterItem(BG_FindItemForHoldable(HI_SLIPPERS)); RegisterItem(BG_FindItemForHoldable(HI_SILENCER)); RegisterItem(BG_FindItemForHoldable(HI_BANDOLIER)); RegisterItem(BG_FindItemForHoldable(HI_LASER)); // JBravo: adding the helmet if (g_RQ3_haveHelmet.integer) RegisterItem(BG_FindItemForHoldable(HI_HELMET)); //Makro - all weapons should be loaded in teamplay //JBravo: and CTF if (g_gametype.integer == GT_TEAMPLAY || g_gametype.integer == GT_CTF || g_gametype.integer == GT_TEAM) { RegisterItem(BG_FindItemForWeapon(WP_M3)); RegisterItem(BG_FindItemForWeapon(WP_MP5)); RegisterItem(BG_FindItemForWeapon(WP_HANDCANNON)); RegisterItem(BG_FindItemForWeapon(WP_SSG3000)); RegisterItem(BG_FindItemForWeapon(WP_M4)); RegisterItem(BG_FindItemForWeapon(WP_AKIMBO)); RegisterItem(BG_FindItemForWeapon(WP_GRENADE)); } }
/* ============== ClearRegisteredItems ============== */ void ClearRegisteredItems( void ) { memset( itemRegistered, 0, sizeof( itemRegistered ) ); // !TODO: Have map determine the base weapons: // players always start with the base weapon RegisterItem( BG_FindItemForWeapon( WP_MACHINEGUN ) ); RegisterItem( BG_FindItemForWeapon( WP_GAUNTLET ) ); if( g_gametype.integer == GT_HARVESTER ) { RegisterItem( BG_FindItem( "Red Cube" ) ); RegisterItem( BG_FindItem( "Blue Cube" ) ); } }
/* ============== ClearRegisteredItems ============== */ void ClearRegisteredItems( void ) { memset( itemRegistered, 0, sizeof( itemRegistered ) ); // players always start with the base weapon RegisterItem( BG_FindItemForWeapon( WP_NIPPER ) ); RegisterItem( BG_FindItemForWeapon( WP_PUNCHY ) ); RegisterItem( BG_FindItemForWeapon( WP_KILLERDUCKS ) ); if ( IsSyc() ) { RegisterItem( BG_FindItemForWeapon( WP_SPRAYPISTOL ) ); } }
/* ============== ClearRegisteredItems ============== */ void ClearRegisteredItems( void ) { memset( itemRegistered, 0, sizeof( itemRegistered ) ); // players always start with the base weapon RegisterItem( BG_FindItemForWeapon( WP_MACHINEGUN ) ); RegisterItem( BG_FindItemForWeapon( WP_GAUNTLET ) ); #ifdef MISSIONPACK if( g_gametype.integer == GT_HARVESTER ) { RegisterItem( BG_FindItem( "Red Cube" ) ); RegisterItem( BG_FindItem( "Blue Cube" ) ); } #endif }
void NPC_ATST_Precache( void ) { G_SoundIndex( "sound/chars/atst/atst_damaged1" ); G_SoundIndex( "sound/chars/atst/atst_damaged2" ); // RegisterItem( BG_FindItemForWeapon( WP_ATST_MAIN )); //precache the weapon //rwwFIXMEFIXME: add this weapon RegisterItem( BG_FindItemForWeapon( WP_BOWCASTER ) ); //precache the weapon RegisterItem( BG_FindItemForWeapon( WP_ROCKET_LAUNCHER ) ); //precache the weapon G_EffectIndex( "env/med_explode2" ); // G_EffectIndex( "smaller_chunks" ); G_EffectIndex( "blaster/smoke_bolton" ); G_EffectIndex( "explosions/droidexplosion1" ); }
static void RegisterAssets( Vehicle_t *pVeh ) { //atst uses turret weapon RegisterItem( BG_FindItemForWeapon( WP_TURRET ) ); //call the standard RegisterAssets now g_vehicleInfo[VEHICLE_BASE].RegisterAssets( pVeh ); }
void ClearRegisteredItems( void ) { memset( itemRegistered, 0, sizeof( itemRegistered ) ); // players always start with the base weapon //RAZMARK: Adding new weapons RegisterItem( BG_FindItemForWeapon( WP_QUANTIZER ) ); }
/* ================= 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; } } } }
//go through all classes on a team and register their //weapons and items for precaching. void G_SiegeRegisterWeaponsAndHoldables( int team ) { siegeTeam_t *stm = BG_SiegeFindThemeForTeam( team ); if ( stm ) { int i = 0; siegeClass_t *scl; while ( i < stm->numClasses ) { scl = stm->classes[i]; if ( scl ) { int j = 0; while ( j < WP_NUM_WEAPONS ) { if ( scl->weapons & (1 << j) ) { //we use this weapon so register it. RegisterItem( BG_FindItemForWeapon( j ) ); } j++; } j = 0; while ( j < HI_NUM_HOLDABLE ) { if ( scl->invenItems & (1 << j) ) { //we use this item so register it. RegisterItem( BG_FindItemForHoldable( j ) ); } j++; } } i++; } } }
static void RegisterAssets( Vehicle_t *pVeh ) { //atst uses turret weapon #ifdef _JK2MP RegisterItem(BG_FindItemForWeapon(WP_TURRET)); #else // PUT SOMETHING HERE... #endif //call the standard RegisterAssets now g_vehicleInfo[VEHICLE_BASE].RegisterAssets( pVeh ); }
/* ================= 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 NPC_Mark2_Precache( void ) { G_SoundIndex( "sound/chars/mark2/misc/mark2_explo" );// blows up on death G_SoundIndex( "sound/chars/mark2/misc/mark2_pain" ); G_SoundIndex( "sound/chars/mark2/misc/mark2_fire" ); G_SoundIndex( "sound/chars/mark2/misc/mark2_move_lp" ); G_EffectIndex( "explosions/droidexplosion1" ); G_EffectIndex( "env/med_explode2" ); G_EffectIndex( "blaster/smoke_bolton" ); G_EffectIndex( "bryar/muzzle_flash" ); RegisterItem( BG_FindItemForWeapon( WP_BRYAR_PISTOL ) ); RegisterItem( BG_FindItemForAmmo( AMMO_METAL_BOLTS ) ); RegisterItem( BG_FindItemForAmmo( AMMO_POWERCELL ) ); RegisterItem( BG_FindItemForAmmo( AMMO_BLASTER ) ); }
void G_Suck( gentity_t *self ) { int wait = self->wait; // if in water disable burning if (!Q_stricmp(self->classname, "grenadeend")){ gitem_t *item; item = BG_FindItemForWeapon( WP_DYNAMITE ); self->s.apos.trDelta[0] = 0; self->s.modelindex = item- bg_itemlist; self->s.modelindex2 = 1; self->item = item; self->s.eType = ET_ITEM; self->r.contents = CONTENTS_TRIGGER2; self->wait = -1; self->flags |= FL_THROWN_ITEM; self->touch = Touch_Item; self->classname = "grenadesit"; self->think = G_KnifeThink; self->nextthink = level.time + 100; self->wait = level.time + 60000; self->r.currentAngles[1] = rand() % 360; self->r.currentAngles[PITCH] = 90; VectorCopy(self->r.currentAngles, self->s.apos.trBase); return; } if(self->s.pos.trType == TR_STATIONARY){ // just to be sure KnifeThink doesn't delete the dynamite self->wait = level.time + 999999; // runs solid checks: is dynamite hovering in the air? G_KnifeThink(self); } self->nextthink = level.time + 100; self->think = G_Suck; self->wait = wait; if (level.time > self->wait && !Q_stricmp(self->classname, "grenade")) G_ExplodeMissile( self ); }
void G_ThrowWeapon( int weapon, gentity_t *ent ) { playerState_t *ps; gitem_t *item; gentity_t *drop; ps = &ent->client->ps; if(!(ps->stats[STAT_WEAPONS] & (1 << weapon))) return; if(weapon == WP_NONE) return; item = BG_FindItemForWeapon( weapon ); drop = G_dropWeapon( ent, item, 0, FL_DROPPED_ITEM | FL_THROWN_ITEM ); if(drop){ trap_SendServerCommand( ent-g_entities, va("print \"%s dropped.\n\"", item->pickup_name)); } // delete weapon from inventory if(bg_weaponlist[weapon].wp_sort == WPS_PISTOL && (ps->stats[STAT_FLAGS] & SF_SEC_PISTOL)){ if (ps->ammo[weapon] < ps->ammo[WP_AKIMBO]) { int ammo = ps->ammo[weapon]; ps->ammo[weapon] = ps->ammo[WP_AKIMBO]; ps->ammo[WP_AKIMBO] = ammo; } if(drop) drop->count= ps->ammo[ WP_AKIMBO ]+1; ps->ammo[ WP_AKIMBO] = 0; ps->stats[STAT_FLAGS] &= ~SF_SEC_PISTOL; } else { if(drop) drop->count= ps->ammo[ weapon ]+1; ps->ammo[ weapon ] = 0; ps->stats[STAT_WEAPONS] &= ~( 1 << weapon ); } }
void NPC_Probe_Precache( void ) { int i; for ( i = 1; i < 4; i++ ) { G_SoundIndex( va( "sound/chars/probe/misc/probetalk%d", i ) ); } G_SoundIndex( "sound/chars/probe/misc/probedroidloop" ); G_SoundIndex( "sound/chars/probe/misc/anger1" ); G_SoundIndex( "sound/chars/probe/misc/fire" ); G_EffectIndex( "chunks/probehead" ); G_EffectIndex( "env/med_explode2" ); G_EffectIndex( "explosions/probeexplosion1" ); G_EffectIndex( "bryar/muzzle_flash" ); RegisterItem( BG_FindItemForAmmo( AMMO_BLASTER ) ); RegisterItem( BG_FindItemForWeapon( WP_BRYAR_PISTOL ) ); }
/* ================= TossClientItems Toss the weapon and powerups for the killed player ================= */ void TossClientItems( gentity_t *self ) { gitem_t *item; int weapon; gentity_t *drop = 0; // 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 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 ( self->client->ps.weaponstate == WEAPON_DROPPING ) { weapon = self->client->pers.cmd.weapon; } if ( !( COM_BitCheck( self->client->ps.weapons, weapon ) ) ) { weapon = WP_NONE; } } // JPW NERVE don't drop these weapon types if ( ( weapon == WP_FLAMETHROWER ) || ( weapon == WP_GARAND ) || ( weapon == WP_MAUSER ) || ( weapon == WP_VENOM ) ) { weapon = WP_NONE; } // jpw if ( weapon > WP_NONE && weapon < WP_MONSTER_ATTACK1 && self->client->ps.ammo[ BG_FindAmmoForWeapon( weapon_t (weapon) )] ) { // find the item type for this weapon item = BG_FindItemForWeapon( weapon_t (weapon) ); // spawn the item // Rafael if ( !( self->client->ps.persistant[PERS_HWEAPON_USE] ) ) { drop = Drop_Item( self, item, 0, qfalse ); // JPW NERVE -- fix ammo counts drop->count = self->client->ps.ammoclip[BG_FindClipForWeapon( weapon_t (weapon) )]; drop->item->quantity = self->client->ps.ammoclip[BG_FindClipForWeapon( weapon_t (weapon) )]; // jpw } } }
void InitShooter( gentity_t *ent, int weapon ) { ent->use = Use_Shooter; ent->s.weapon = weapon; RegisterItem( BG_FindItemForWeapon( weapon ) ); G_SetMovedir( &ent->s.angles, &ent->movedir ); if ( !ent->random ) { ent->random = 1.0; } ent->random = sinf( M_PI * ent->random / 180 ); // target might be a moving object, so we can't set movedir for it if ( ent->target ) { ent->think = InitShooter_Finish; ent->nextthink = level.time + 500; } trap->SV_LinkEntity( (sharedEntity_t *)ent ); }
void G_DropBinocs( gentity_t *ent ) { 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( WP_BINOCULARS ); 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 = LaunchBinocs( item, org, velocity, client->ps.clientNum ); COM_BitClear( client->ps.weapons, WP_BINOCULARS ); // Clear out empty weapon, change to next best weapon G_AddEvent( ent, EV_WEAPONSWITCHED, 0 ); if( WP_BINOCULARS == client->ps.weapon ) client->ps.weapon = 0; client->ps.ammoclip[BG_FindClipForWeapon(WP_BINOCULARS)] = 0; }
/* ============== ClearRegisteredItems ============== */ void ClearRegisteredItems( void ) { int i = 0; memset( itemRegistered, 0, sizeof( itemRegistered ) ); // Navy Seals ++ if ( g_cheats.integer == 0 ) { for ( i = 1 ; i < WP_NUM_WEAPONS - 1; i++ ) { // if ( i == WP_NUTSHELL ) continue; if ( i == WP_NONE ) { continue; } RegisterItem( BG_FindItemForWeapon( i ) ); } } // Navy Seals -- }
/* ================ AICast_DelayedSpawnCast ================ */ void AICast_DelayedSpawnCast( gentity_t *ent, int castType ) { int i; // ............................ // head separation if ( !ent->aiSkin ) { G_SpawnString( "skin", "", &ent->aiSkin ); } if ( !ent->aihSkin ) { G_SpawnString( "head", "default", &ent->aihSkin ); } G_SpawnInt( "aiteam", "-1", &ent->aiTeam ); // ............................ //----(SA) make sure client registers the default weapons for this char for ( i = 0; aiDefaults[ent->aiCharacter].weapons[i]; i++ ) { RegisterItem( BG_FindItemForWeapon( aiDefaults[ent->aiCharacter].weapons[i] ) ); } //----(SA) end // we have to wait a bit before spawning it, otherwise the server will just delete it, since it's treated like a client ent->think = AIChar_spawn; ent->nextthink = level.time + FRAMETIME * 4; // have to wait more than 3 frames, since the server runs 3 frames before it clears all clients // we don't really want to start this character right away, but if we don't spawn the client // now, if the game gets saved after the character spawns in, when it gets re-loaded, the client // won't get spawned properly. if ( ent->spawnflags & 1 ) { // TriggerSpawn ent->AIScript_AlertEntity = AIChar_AIScript_AlertEntity; ent->aiInactive = qtrue; } // RF, had to move this down since some dev maps don't properly spawn the guys in, so we // get a crash when transitioning between levels after they all spawn at once (overloading // the client/server command buffers) ent->nextthink += FRAMETIME * ( ( numSpawningCast + 1 ) / 3 ); // space them out a bit so we don't overflow the client ent->aiCharacter = castType; numSpawningCast++; }
void InitShooter( gentity_t *ent, int weapon ) { ent->use = Use_Shooter; ent->s.weapon = weapon; #ifdef SMOKINGUNS if(weapon != WP_NONE) #endif RegisterItem( BG_FindItemForWeapon( weapon ) ); G_SetMovedir( ent->s.angles, ent->movedir ); if ( !ent->random ) { ent->random = 1.0; } ent->random = sin( M_PI * ent->random / 180 ); // target might be a moving object, so we can't set movedir for it if ( ent->target ) { ent->think = InitShooter_Finish; ent->nextthink = level.time + 500; } trap_LinkEntity( ent ); }
/* ================== BotRandomWeaponName ================== */ char *BotRandomWeaponName(void) { int rnd; gitem_t *item; #if 0 rnd = 1 + random() * ( (float)WP_NUM_WEAPONS - 1.1f ); #else // skip grapple rnd = 1 + random() * ( (float)WP_NUM_WEAPONS - 2.1f ); // only happens if there is a weapon after grapple, like in Team Arena if ( rnd >= WP_GRAPPLING_HOOK ) { rnd++; } #endif item = BG_FindItemForWeapon( rnd ); if ( item ) { return item->pickup_name; } return "[unknown weapon]"; }
/* =============== UI_PlayerInfo_SetWeapon =============== */ static void UI_PlayerInfo_SetWeapon( uiPlayerInfo_t *pi, weapon_t weaponNum ) { #ifdef TA_WEAPSYS int i; #else gitem_t * item; #endif char path[MAX_QPATH]; pi->currentWeapon = weaponNum; #ifndef TA_WEAPSYS tryagain: #endif pi->realWeapon = weaponNum; #ifdef TA_WEAPSYS for (i = 0; i < MAX_HANDS; i++) { pi->weaponModel[i] = 0; pi->barrelModel[i] = 0; pi->flashModel[i] = 0; } #else pi->weaponModel = 0; pi->barrelModel = 0; pi->flashModel = 0; #endif if ( weaponNum == WP_NONE ) { return; } #ifdef TA_WEAPSYS for (i = 0; i < MAX_HANDS; i++) { if (bg_weapongroupinfo[weaponNum].weapon[i]->model[0] == '\0') continue; pi->weaponModel[i] = trap_R_RegisterModel(bg_weapongroupinfo[weaponNum].weapon[i]->model); strcpy( path, bg_weapongroupinfo[weaponNum].weapon[i]->model ); COM_StripExtension(path, path, sizeof(path)); strcat( path, "_barrel.md3" ); pi->barrelModel[i] = trap_R_RegisterModel( path ); strcpy( path, bg_weapongroupinfo[weaponNum].weapon[i]->model ); COM_StripExtension(path, path, sizeof(path)); strcat( path, "_flash.md3" ); pi->flashModel[i] = trap_R_RegisterModel( path ); VectorCopy(bg_weapongroupinfo[weaponNum].weapon[i]->flashColor, pi->flashDlightColor[i]); } #else item = BG_FindItemForWeapon( weaponNum ); if ( item ) { pi->weaponModel = trap_R_RegisterModel( item->world_model[0] ); } if( pi->weaponModel == 0 ) { if( weaponNum == WP_MACHINEGUN ) { weaponNum = WP_NONE; goto tryagain; } weaponNum = WP_MACHINEGUN; goto tryagain; } COM_StripExtension( item->world_model[0], path, sizeof(path) ); Q_strcat( path, sizeof(path), "_barrel.md3" ); pi->barrelModel = trap_R_RegisterModel( path ); COM_StripExtension( item->world_model[0], path, sizeof(path) ); Q_strcat( path, sizeof(path), "_flash.md3" ); pi->flashModel = trap_R_RegisterModel( path ); switch( weaponNum ) { case WP_GAUNTLET: MAKERGB( pi->flashDlightColor, 0.6f, 0.6f, 1 ); break; case WP_MACHINEGUN: MAKERGB( pi->flashDlightColor, 1, 1, 0 ); break; case WP_SHOTGUN: MAKERGB( pi->flashDlightColor, 1, 1, 0 ); break; case WP_GRENADE_LAUNCHER: MAKERGB( pi->flashDlightColor, 1, 0.7f, 0.5f ); break; case WP_ROCKET_LAUNCHER: MAKERGB( pi->flashDlightColor, 1, 0.75f, 0 ); break; case WP_LIGHTNING: MAKERGB( pi->flashDlightColor, 0.6f, 0.6f, 1 ); break; case WP_RAILGUN: MAKERGB( pi->flashDlightColor, 1, 0.5f, 0 ); break; case WP_PLASMAGUN: MAKERGB( pi->flashDlightColor, 0.6f, 0.6f, 1 ); break; case WP_BFG: MAKERGB( pi->flashDlightColor, 1, 0.7f, 1 ); break; case WP_GRAPPLING_HOOK: MAKERGB( pi->flashDlightColor, 0.6f, 0.6f, 1 ); break; #ifdef MISSIONPACK case WP_NAILGUN: MAKERGB( pi->flashDlightColor, 1, 0.75f, 0 ); break; case WP_PROX_LAUNCHER: MAKERGB( pi->flashDlightColor, 1, 0.70f, 0 ); break; case WP_CHAINGUN: MAKERGB( pi->flashDlightColor, 1, 1, 0 ); break; #endif default: MAKERGB( pi->flashDlightColor, 1, 1, 1 ); break; } #endif }
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])] + client->ps.ammoclip[BG_FindClipForWeapon(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; }
/*QUAKED worldspawn (0 0 0) ? RED_HAS_BOMB BLUE_HAS_BOMB Every map should have exactly one worldspawn. The bomb flags are only used for the tactical gametype. "music" music wav file "gravity" 800 is default gravity "message" Text to print during connection process "atmosphere" used to create atmospheric effects "T=xxxx" type of effect (SNOW or RAIN) "D=xx xx" drops (base and gust, max 2000, def: 500 500) "S=xx xx" splashes on/off (water and land, def: 1 1) "B=xx xx" min and max base time (in secs, def: 5 10) "C=xx xx" min and max change time (in secs, def: 1 1) "G=xx xx" min and max gust time (in secs, def: 0 2) "BV=xx xx" base wind direction vector (def: 0 0) "GV=xx xx" gust wind direction vector (def: 0 100) */ void SP_worldspawn( void ) { char *s; int i; G_SpawnString( "classname", "", &s ); if ( Q_stricmp( s, "worldspawn" ) ) { G_Error( "SP_worldspawn: The first entity isn't 'worldspawn'" ); } // make some data visible to connecting client trap_SetConfigstring( CS_GAME_VERSION, VERSION_SHORT ); trap_SetConfigstring( CS_LEVEL_START_TIME, va("%i", level.startTime ) ); G_SpawnString( "music", "", &s ); trap_SetConfigstring( CS_MUSIC, s ); G_SpawnString( "message", "", &s ); trap_SetConfigstring( CS_MESSAGE, s ); // map specific message trap_SetConfigstring( CS_MOTD, g_motd.string ); // message of the day G_SpawnString( "gravity", "800", &s ); trap_Cvar_Set( "g_gravity", s ); G_SpawnString( "enableDust", "0", &s ); trap_Cvar_Set( "g_enableDust", s ); G_SpawnString( "enableBreath", "0", &s ); trap_Cvar_Set( "g_enableBreath", s ); G_SpawnString( "atmosphere", "", &s ); trap_SetConfigstring( CS_ATMOSEFFECT, s ); // Atmospheric effect g_entities[ENTITYNUM_WORLD].s.number = ENTITYNUM_WORLD; g_entities[ENTITYNUM_WORLD].classname = "worldspawn"; // see if a team has the bomb G_SpawnInt( "spawnflags", "0", &i ); level.bombTeam = ( i & 3 ); // register the bomb if one is here if ( ( i & 3 ) && g_gametype.integer == GT_TACTICAL ) RegisterItem( BG_FindItemForWeapon( WP_BLAST ) ); // round time setting if ( g_mapRoundTime.integer ) { G_SpawnInt( "roundtime", va( "%i", DEFAULT_ROUNDTIME ), &i ); if ( i < MIN_ROUNDTIME || i > MAX_ROUNDTIME ) i = DEFAULT_ROUNDTIME; trap_Cvar_Set( "roundtime", va("%i", i ) ); } // check weapon enabling/disabling (GT_TACTICAL only) if ( g_gametype.integer == GT_TACTICAL ) { char name[128]; gitem_t *item; // parse map weapon disabling information if ( g_mapWeaponDisable.integer ) { for ( item = bg_itemlist + 1; item->classname; item++ ) { if ( item->giType == IT_WEAPON ) { Com_sprintf(name, sizeof(name), "disable_%s", item->classname); G_SpawnInt( name, "0", &i ); if ( i || trap_Cvar_VariableIntegerValue( name ) ) trap_Cvar_Set( name, va("%i", i ) ); } } } // register enabled weapons level.weaponsEnabled = 0; for ( i = 1 ; i < WP_NUM_WEAPONS - 1; i++ ) { // without Blastpack Com_sprintf(name, sizeof(name), "disable_%s", BG_FindItemForWeapon(i)->classname); if ( !trap_Cvar_VariableIntegerValue( name ) ) { RegisterItem( BG_FindItemForWeapon(i) ); level.weaponsEnabled |= ( 1 << i ); } } } // see if we want a warmup time trap_SetConfigstring( CS_WARMUP, "" ); if ( g_restarted.integer ) { trap_Cvar_Set( "g_restarted", "0" ); level.warmupTime = 0; } else if ( g_doWarmup.integer ) { // Turn it on level.warmupTime = -1; trap_SetConfigstring( CS_WARMUP, va("%i", level.warmupTime) ); G_LogPrintf( "Warmup:\n" ); } }
void G_MissileImpact( gentity_t *ent, trace_t *trace ) { #else void G_MissileImpact( gentity_t *ent, trace_t *trace, int shaderNum ) { #endif gentity_t *other; qboolean hitClient = qfalse; #ifndef SMOKINGUNS #ifdef MISSIONPACK vec3_t forward, impactpoint, bouncedir; int eFlags; #endif #else qboolean hitKnife = qfalse; vec3_t bottledirs[ALC_COUNT]; #endif other = &g_entities[trace->entityNum]; #ifndef SMOKINGUNS // check for bounce if ( !other->takedamage && ( ent->s.eFlags & ( EF_BOUNCE | EF_BOUNCE_HALF ) ) ) { G_BounceMissile( ent, trace ); G_AddEvent( ent, EV_GRENADE_BOUNCE, 0 ); return; } #ifdef MISSIONPACK if ( other->takedamage ) { if ( ent->s.weapon != WP_PROX_LAUNCHER ) { if ( other->client && other->client->invulnerabilityTime > level.time ) { // VectorCopy( ent->s.pos.trDelta, forward ); VectorNormalize( forward ); if (G_InvulnerabilityEffect( other, forward, ent->s.pos.trBase, impactpoint, bouncedir )) { VectorCopy( bouncedir, trace->plane.normal ); eFlags = ent->s.eFlags & EF_BOUNCE_HALF; ent->s.eFlags &= ~EF_BOUNCE_HALF; G_BounceMissile( ent, trace ); ent->s.eFlags |= eFlags; } ent->target_ent = other; return; } } } #endif // impact damage if (other->takedamage) { #else if(other->takedamage) hitKnife = qtrue; // check for bounce if ( ( ent->s.eFlags & ( EF_BOUNCE | EF_BOUNCE_HALF ) ) ) { G_BounceMissile( ent, trace ); return; } if (other->takedamage && ent->s.weapon != WP_DYNAMITE) { #endif // FIXME: wrong damage direction? if ( ent->damage ) { vec3_t velocity; if( LogAccuracyHit( other, &g_entities[ent->r.ownerNum] ) ) { g_entities[ent->r.ownerNum].client->accuracy_hits++; hitClient = qtrue; } BG_EvaluateTrajectoryDelta( &ent->s.pos, level.time, velocity ); if ( VectorLength( velocity ) == 0 ) { velocity[2] = 1; // stepped on a grenade } #ifndef SMOKINGUNS G_Damage (other, ent, &g_entities[ent->r.ownerNum], velocity, ent->s.origin, ent->damage, 0, ent->methodOfDeath); #else // you can't make dynamite exploding by using a knife if(!(ent->s.weapon == WP_KNIFE && other->s.weapon == WP_DYNAMITE && other->s.eType == ET_ITEM)){ // prepare breakable, if not already initialized if(!(other->flags & FL_BREAKABLE_INIT)) G_BreakablePrepare(other, shaderNum); G_Damage (other, ent, &g_entities[ent->r.ownerNum], velocity, ent->s.origin, ent->damage, 0, ent->methodOfDeath); } #endif } } #ifndef SMOKINGUNS if( ent->s.weapon == WP_PROX_LAUNCHER ) { if( ent->s.pos.trType != TR_GRAVITY ) { return; } // if it's a player, stick it on to them (flag them and remove this entity) if( other->s.eType == ET_PLAYER && other->health > 0 ) { ProximityMine_Player( ent, other ); return; } SnapVectorTowards( trace->endpos, ent->s.pos.trBase ); G_SetOrigin( ent, trace->endpos ); ent->s.pos.trType = TR_STATIONARY; VectorClear( ent->s.pos.trDelta ); G_AddEvent( ent, EV_PROXIMITY_MINE_STICK, trace->surfaceFlags ); ent->think = ProximityMine_Activate; ent->nextthink = level.time + 2000; vectoangles( trace->plane.normal, ent->s.angles ); ent->s.angles[0] += 90; // link the prox mine to the other entity ent->enemy = other; ent->die = ProximityMine_Die; VectorCopy(trace->plane.normal, ent->movedir); VectorSet(ent->r.mins, -4, -4, -4); VectorSet(ent->r.maxs, 4, 4, 4); trap_LinkEntity(ent); return; } if (!strcmp(ent->classname, "hook")) { gentity_t *nent; vec3_t v; nent = G_Spawn(); if ( other->takedamage && other->client ) { G_AddEvent( nent, EV_MISSILE_HIT, DirToByte( trace->plane.normal ) ); nent->s.otherEntityNum = other->s.number; ent->enemy = other; v[0] = other->r.currentOrigin[0] + (other->r.mins[0] + other->r.maxs[0]) * 0.5; v[1] = other->r.currentOrigin[1] + (other->r.mins[1] + other->r.maxs[1]) * 0.5; v[2] = other->r.currentOrigin[2] + (other->r.mins[2] + other->r.maxs[2]) * 0.5; SnapVectorTowards( v, ent->s.pos.trBase ); // save net bandwidth } else { VectorCopy(trace->endpos, v); G_AddEvent( nent, EV_MISSILE_MISS, DirToByte( trace->plane.normal ) ); ent->enemy = NULL; } SnapVectorTowards( v, ent->s.pos.trBase ); // save net bandwidth nent->freeAfterEvent = qtrue; // change over to a normal entity right at the point of impact nent->s.eType = ET_GENERAL; ent->s.eType = ET_GRAPPLE; G_SetOrigin( ent, v ); G_SetOrigin( nent, v ); ent->think = Weapon_HookThink; ent->nextthink = level.time + FRAMETIME; ent->parent->client->ps.pm_flags |= PMF_GRAPPLE_PULL; VectorCopy( ent->r.currentOrigin, ent->parent->client->ps.grapplePoint); trap_LinkEntity( ent ); trap_LinkEntity( nent ); return; } #endif // is it cheaper in bandwidth to just remove this ent and create a new // one, rather than changing the missile into the explosion? #ifndef SMOKINGUNS if ( other->takedamage && other->client ) { #else // alcoohol impact if( !Q_stricmp(ent->classname, "alcohol")){ // no event //G_AddEvent( ent, EV_MISSILE_ALCOHOL, DirToByte( trace->plane.normal)); } else if( !Q_stricmp(ent->classname, "molotov")){ // we have to launch the whiskey drops int i; // set the directions for(i = 0; i < ALC_COUNT; i++){ int temp; VectorSet(bottledirs[i], (rand()%10)-5, (rand()%10)-5, (rand()%10)-3); // direction has to be exactly the same (client and server) temp = DirToByte(bottledirs[i]); ByteToDir(temp, bottledirs[i]); } // dirs BG_DirsToEntityState(&ent->s, bottledirs); // burning if(ent->s.apos.trDelta[0]) G_AddEvent( ent, EV_MISSILE_FIRE, DirToByte( trace->plane.normal)); // not burning else G_AddEvent( ent, EV_MISSILE_MISS, DirToByte( trace->plane.normal)); } else if ( other->takedamage && other->client ) { #endif G_AddEvent( ent, EV_MISSILE_HIT, DirToByte( trace->plane.normal ) ); ent->s.otherEntityNum = other->s.number; #ifndef SMOKINGUNS } else if( trace->surfaceFlags & SURF_METALSTEPS ) { #else } else if( trace->surfaceFlags & SURF_METAL ) { #endif G_AddEvent( ent, EV_MISSILE_MISS_METAL, DirToByte( trace->plane.normal ) ); } else { G_AddEvent( ent, EV_MISSILE_MISS, DirToByte( trace->plane.normal ) ); } #ifndef SMOKINGUNS ent->freeAfterEvent = qtrue; // change over to a normal entity right at the point of impact ent->s.eType = ET_GENERAL; #else if(Q_stricmp(ent->classname, "knife")){ ent->freeAfterEvent = qtrue; // change over to a normal entity right at the point of impact ent->s.eType = ET_GENERAL; } else { vec3_t dir; gitem_t *item; item = BG_FindItemForWeapon(WP_KNIFE); ent->s.modelindex = item-bg_itemlist; ent->s.modelindex2 = 1; ent->item = item; ent->s.eType = ET_ITEM; ent->s.pos.trType = TR_GRAVITY; ent->physicsBounce = 0.01f; ent->r.contents = CONTENTS_TRIGGER; ent->touch = Touch_Item; ent->nextthink = level.time + 100; ent->think = G_KnifeThink; ent->wait = level.time + 30000; ent->flags |= FL_THROWN_ITEM; vectoangles(ent->s.pos.trDelta, dir); VectorCopy(dir, ent->s.apos.trBase); VectorCopy(dir, ent->r.currentAngles); } //modified by Spoon END #endif SnapVectorTowards( trace->endpos, ent->s.pos.trBase ); // save net bandwidth G_SetOrigin( ent, trace->endpos ); // splash damage (doesn't apply to person directly hit) if ( ent->splashDamage ) { if( G_RadiusDamage( trace->endpos, ent->parent, ent->splashDamage, ent->splashRadius, other, ent->splashMethodOfDeath ) ) { if( !hitClient ) { g_entities[ent->r.ownerNum].client->accuracy_hits++; } } } // spawn alcohol missiles #ifdef SMOKINGUNS if(!Q_stricmp(ent->classname, "molotov")){ BottleBreak( ent, trace->endpos, trace->plane.normal, bottledirs); } #endif trap_LinkEntity( ent ); } /* ================ G_RunMissile ================ */ void G_RunMissile( gentity_t *ent ) { vec3_t origin; trace_t tr; int passent; #ifdef SMOKINGUNS int shaderNum; gentity_t *traceEnt; #endif // get current position BG_EvaluateTrajectory( &ent->s.pos, level.time, origin ); // if this missile bounced off an invulnerability sphere if ( ent->target_ent ) { passent = ent->target_ent->s.number; } #ifndef SMOKINGUNS // prox mines that left the owner bbox will attach to anything, even the owner else if (ent->s.weapon == WP_PROX_LAUNCHER && ent->count) { passent = ENTITYNUM_NONE; } #endif else { // ignore interactions with the missile owner passent = ent->r.ownerNum; } // trace a line from the previous position to the current position #ifndef SMOKINGUNS trap_Trace( &tr, ent->r.currentOrigin, ent->r.mins, ent->r.maxs, origin, passent, ent->clipmask ); #else shaderNum = trap_Trace_New2( &tr, ent->r.currentOrigin, ent->r.mins, ent->r.maxs, origin, passent, ent->clipmask ); traceEnt = &g_entities[tr.entityNum]; #endif if ( tr.startsolid || tr.allsolid ) { // make sure the tr.entityNum is set to the entity we're stuck in #ifndef SMOKINGUNS trap_Trace( &tr, ent->r.currentOrigin, ent->r.mins, ent->r.maxs, ent->r.currentOrigin, passent, ent->clipmask ); #else trap_Trace_New( &tr, ent->r.currentOrigin, ent->r.mins, ent->r.maxs, ent->r.currentOrigin, passent, ent->clipmask ); #endif tr.fraction = 0; } else { VectorCopy( tr.endpos, ent->r.currentOrigin ); } trap_LinkEntity( ent ); if ( tr.fraction != 1 ) { #ifdef SMOKINGUNS VectorCopy(origin, ent->s.origin2); #endif // never explode or bounce on sky if ( tr.surfaceFlags & SURF_NOIMPACT ) { // If grapple, reset owner if (ent->parent && ent->parent->client && ent->parent->client->hook == ent) { ent->parent->client->hook = NULL; } // if its a dynamite or molotov let it move 10 seconds before deleting it #ifdef SMOKINGUNS if(ent->s.weapon == WP_DYNAMITE || ent->s.weapon == WP_MOLOTOV || ent->s.weapon == WP_KNIFE){ if(ent->mappart >= level.time && ent->mappart){ goto think; } else if(ent->mappart){ ent->mappart = 0; } else { ent->mappart = level.time + 5000; goto think; } } #endif G_FreeEntity( ent ); return; } #ifndef SMOKINGUNS G_MissileImpact( ent, &tr ); if ( ent->s.eType != ET_MISSILE ) { #else G_MissileImpact( ent, &tr, shaderNum ); if ( ent->s.eType != ET_MISSILE && ent->s.eType != ET_ITEM) { #endif return; // exploded } } #ifndef SMOKINGUNS // if the prox mine wasn't yet outside the player body if (ent->s.weapon == WP_PROX_LAUNCHER && !ent->count) { // check if the prox mine is outside the owner bbox trap_Trace( &tr, ent->r.currentOrigin, ent->r.mins, ent->r.maxs, ent->r.currentOrigin, ENTITYNUM_NONE, ent->clipmask ); if (!tr.startsolid || tr.entityNum != ent->r.ownerNum) { ent->count = 1; } } #endif think: // check think function after bouncing G_RunThink( ent ); } //============================================================================= #ifndef SMOKINGUNS /* ================= fire_plasma ================= */ gentity_t *fire_plasma (gentity_t *self, vec3_t start, vec3_t dir) { gentity_t *bolt; VectorNormalize (dir); bolt = G_Spawn(); bolt->classname = "plasma"; bolt->nextthink = level.time + 10000; bolt->think = G_ExplodeMissile; bolt->s.eType = ET_MISSILE; bolt->r.svFlags = SVF_USE_CURRENT_ORIGIN; bolt->s.weapon = WP_PLASMAGUN; bolt->r.ownerNum = self->s.number; bolt->parent = self; bolt->damage = 20; bolt->splashDamage = 15; bolt->splashRadius = 20; bolt->methodOfDeath = MOD_PLASMA; bolt->splashMethodOfDeath = MOD_PLASMA_SPLASH; bolt->clipmask = MASK_SHOT; bolt->target_ent = NULL; bolt->s.pos.trType = TR_LINEAR; bolt->s.pos.trTime = level.time - MISSILE_PRESTEP_TIME; // move a bit on the very first frame VectorCopy( start, bolt->s.pos.trBase ); VectorScale( dir, 2000, bolt->s.pos.trDelta ); SnapVector( bolt->s.pos.trDelta ); // save net bandwidth VectorCopy (start, bolt->r.currentOrigin); return bolt; } //============================================================================= /* ================= fire_grenade ================= */ gentity_t *fire_grenade (gentity_t *self, vec3_t start, vec3_t dir) { gentity_t *bolt; VectorNormalize (dir); bolt = G_Spawn(); bolt->classname = "grenade"; bolt->nextthink = level.time + 2500; bolt->think = G_ExplodeMissile; bolt->s.eType = ET_MISSILE; bolt->r.svFlags = SVF_USE_CURRENT_ORIGIN; bolt->s.weapon = WP_GRENADE_LAUNCHER; bolt->s.eFlags = EF_BOUNCE_HALF; bolt->r.ownerNum = self->s.number; bolt->parent = self; bolt->damage = 100; bolt->splashDamage = 100; bolt->splashRadius = 150; bolt->methodOfDeath = MOD_GRENADE; bolt->splashMethodOfDeath = MOD_GRENADE_SPLASH; bolt->clipmask = MASK_SHOT; bolt->target_ent = NULL; bolt->s.pos.trType = TR_GRAVITY; bolt->s.pos.trTime = level.time - MISSILE_PRESTEP_TIME; // move a bit on the very first frame VectorCopy( start, bolt->s.pos.trBase ); VectorScale( dir, 700, bolt->s.pos.trDelta ); SnapVector( bolt->s.pos.trDelta ); // save net bandwidth VectorCopy (start, bolt->r.currentOrigin); return bolt; }
int ThrowWeapon(gentity_t * ent, qboolean forceThrow) { gclient_t *client; usercmd_t *ucmd; gitem_t *xr_item; gentity_t *xr_drop; int weap; client = ent->client; ucmd = &ent->client->pers.cmd; if (!forceThrow) if ((ucmd->buttons & BUTTON_ATTACK) || client->ps.weaponTime > 0) return 0; //Elder: remove zoom bits Cmd_Unzoom(ent); // JBravo: simulate AQ drop weapon for akimbo with no special weap if (client->ps.weapon == WP_AKIMBO && client->uniqueWeapons == 0) { trap_SendServerCommand(ent - g_entities, va("stuff weapon %i\n", WP_PISTOL)); return 0; } weap = 0; if (client->uniqueWeapons > 0) { if (client->ps.weapon == WP_AKIMBO || client->ps.weapon == WP_PISTOL || client->ps.weapon == WP_GRENADE || client->ps.weapon == WP_KNIFE || client->ps.weapon == WP_NONE) // shouldn't have to worry about NONE, but just in case { weap = client->ps.stats[STAT_WEAPONS]; if ((client->ps.stats[STAT_WEAPONS] & (1 << WP_M4)) == (1 << WP_M4)) weap = WP_M4; if ((client->ps.stats[STAT_WEAPONS] & (1 << WP_M3)) == (1 << WP_M3)) weap = WP_M3; if ((client->ps.stats[STAT_WEAPONS] & (1 << WP_MP5)) == (1 << WP_MP5)) weap = WP_MP5; if ((client->ps.stats[STAT_WEAPONS] & (1 << WP_HANDCANNON)) == (1 << WP_HANDCANNON)) weap = WP_HANDCANNON; if ((client->ps.stats[STAT_WEAPONS] & (1 << WP_SSG3000)) == (1 << WP_SSG3000)) weap = WP_SSG3000; if (weap == 0) return 0; } else { weap = client->ps.weapon; } xr_item = BG_FindItemForWeapon(weap); client->pers.hadUniqueWeapon[weap] = qtrue; //Elder: for immediate weapon drops if (client->ps.weapon == weap) { client->ps.stats[STAT_RQ3] |= RQ3_THROWWEAPON; trap_SendServerCommand(ent - g_entities, va("rq3_cmd %i", SELECTPISTOL)); } client->weaponCount[weap]--; if (client->weaponCount[weap] == 0) client->ps.stats[STAT_WEAPONS] &= ~(1 << weap); xr_drop = dropWeapon(ent, xr_item, 0, FL_DROPPED_ITEM | FL_THROWN_ITEM); xr_drop->count = -1; // XRAY FMJ 0 is already taken, -1 means no ammo // remember who dropped you, child! xr_drop->s.otherEntityNum = client->ps.clientNum; client->uniqueWeapons--; } return weap; }
//----------------------------------------------------- qboolean turret_base_spawn_top( gentity_t *base ) { vec3_t org; int t; gentity_t *top = G_Spawn(); if ( !top ) { return qfalse; } top->s.modelindex = G_ModelIndex( "models/map_objects/hoth/turret_top_new.md3" ); top->s.modelindex2 = G_ModelIndex( "models/map_objects/hoth/turret_top.md3" ); G_SetAngles( top, base->s.angles ); VectorCopy( base->s.origin, org ); org[2] += 128; G_SetOrigin( top, org ); base->r.ownerNum = top->s.number; top->r.ownerNum = base->s.number; if ( base->team && base->team[0] && //g_gametype.integer == GT_SIEGE && !base->teamnodmg) { base->teamnodmg = atoi(base->team); } base->team = NULL; top->teamnodmg = base->teamnodmg; top->alliedTeam = base->alliedTeam; base->s.eType = ET_GENERAL; // Set up our explosion effect for the ExplodeDeath code.... G_EffectIndex( "turret/explode" ); G_EffectIndex( "sparks/spark_exp_nosnd" ); G_EffectIndex( "turret/hoth_muzzle_flash" ); // this is really the pitch angle..... top->speed = 0; // this is a random time offset for the no-enemy-search-around-mode top->count = random() * 9000; if ( !base->health ) { base->health = 3000; } top->health = base->health; G_SpawnInt( "showhealth", "0", &t ); if (t) { //a non-0 maxhealth value will mean we want to show the health on the hud top->maxHealth = base->health; //acts as "maxhealth" G_ScaleNetHealth(top); base->maxHealth = base->health; G_ScaleNetHealth(base); } base->takedamage = qtrue; base->pain = TurretBasePain; base->die = bottom_die; //design specified shot speed G_SpawnFloat( "shotspeed", "1100", &base->mass ); top->mass = base->mass; //even if we don't want to show health, let's at least light the crosshair up properly over ourself if ( !top->s.teamowner ) { top->s.teamowner = top->alliedTeam; } base->alliedTeam = top->alliedTeam; base->s.teamowner = top->s.teamowner; base->s.shouldtarget = qtrue; top->s.shouldtarget = qtrue; //link them to each other base->target_ent = top; top->target_ent = base; //top->s.owner = MAX_CLIENTS; //not owned by any client // search radius if ( !base->radius ) { base->radius = 1024; } top->radius = base->radius; // How quickly to fire if ( !base->wait ) { base->wait = 300 + random() * 55; } top->wait = base->wait; if ( !base->splashDamage ) { base->splashDamage = 300; } top->splashDamage = base->splashDamage; if ( !base->splashRadius ) { base->splashRadius = 128; } top->splashRadius = base->splashRadius; // how much damage each shot does if ( !base->damage ) { base->damage = 100; } top->damage = base->damage; // how fast it turns if ( !base->speed ) { base->speed = 20; } top->speed = base->speed; VectorSet( top->r.maxs, 48.0f, 48.0f, 16.0f ); VectorSet( top->r.mins, -48.0f, -48.0f, 0.0f ); // Precache moving sounds //G_SoundIndex( "sound/chars/turret/startup.wav" ); //G_SoundIndex( "sound/chars/turret/shutdown.wav" ); //G_SoundIndex( "sound/chars/turret/ping.wav" ); G_SoundIndex( "sound/vehicles/weapons/hoth_turret/turn.wav" ); top->genericValue13 = G_EffectIndex( "turret/hoth_muzzle_flash" ); top->genericValue14 = G_EffectIndex( "turret/hoth_shot" ); top->genericValue15 = G_EffectIndex( "turret/hoth_impact" ); top->r.contents = CONTENTS_BODY; //base->max_health = base->health; top->takedamage = qtrue; top->pain = TurretPain; top->die = auto_turret_die; top->material = MAT_METAL; //base->r.svFlags |= SVF_NO_TELEPORT|SVF_NONNPC_ENEMY|SVF_SELF_ANIMATING; // Register this so that we can use it for the missile effect RegisterItem( BG_FindItemForWeapon( WP_EMPLACED_GUN )); // But set us as a turret so that we can be identified as a turret top->s.weapon = WP_EMPLACED_GUN; trap_LinkEntity( top ); return qtrue; }