/* =============== SV_Sound =============== */ void SV_Sound( vec3_t *org, int entnum, int channel, const char *sound_name, float volume, float mindist, float pitch, float maxdist, qboolean streamed ) { int i; for( i = 0; i < sv_maxclients->integer; i++ ) { client_t *client = &svs.clients[ i ]; server_sound_t *sound; if( client->state != CS_ACTIVE ) continue; if( client->number_of_server_sounds >= MAX_SERVER_SOUNDS ) continue; sound = &client->server_sounds[ client->number_of_server_sounds ]; sound->stop_flag = 0; sound->entity_number = entnum; if( org ) { VectorCopy( *org, sound->origin ); } else { VectorClear( sound->origin ); } sound->channel = channel; sound->volume = volume; sound->min_dist = mindist; sound->pitch = pitch; sound->maxDist = maxdist; sound->sound_index = SV_SoundIndex( sound_name, streamed ); sound->streamed = streamed; client->number_of_server_sounds++; } }
/* * The global "activator" should be set to * the entity that initiated the firing. * * If self.delay is set, a DelayedUse entity * will be created that will actually do the * SUB_UseTargets after that many seconds have passed. * * Centerprints any self.message to the activator. * * Search for (string)targetname in all entities that * match (string)self.target and call their .use function */ void G_UseTargets(edict_t *ent, edict_t *activator) { edict_t *t; if (!ent || !activator) { return; } /* check for a delay */ if (ent->delay) { /* create a temp object to fire at a later time */ t = G_Spawn(); t->classname = "DelayedUse"; t->nextthink = level.time + ent->delay; t->think = Think_Delay; t->activator = activator; if (!activator) { PF_dprintf("Think_Delay with no activator\n"); } t->message = ent->message; t->target = ent->target; t->killtarget = ent->killtarget; return; } /* print the message */ if ((ent->message) && !(activator->svflags & SVF_MONSTER)) { PF_centerprintf(activator, "%s", ent->message); if (ent->noise_index) { PF_StartSound(activator, CHAN_AUTO, ent->noise_index, 1, ATTN_NORM, 0); } else { PF_StartSound(activator, CHAN_AUTO, SV_SoundIndex("misc/talk1.wav"), 1, ATTN_NORM, 0); } } /* kill killtargets */ if (ent->killtarget) { t = NULL; while ((t = G_Find(t, FOFS(targetname), ent->killtarget))) { /* decrement secret count if target_secret is removed */ if (!Q_stricmp(t->classname, "target_secret")) { level.total_secrets--; } /* same deal with target_goal, but also turn off CD music if applicable */ else if (!Q_stricmp(t->classname, "target_goal")) { level.total_goals--; if (level.found_goals >= level.total_goals) { PF_Configstring(CS_CDTRACK, "0"); } } G_FreeEdict(t); if (!ent->inuse) { PF_dprintf("entity was removed while using killtargets\n"); return; } } } /* fire targets */ if (ent->target) { t = NULL; while ((t = G_Find(t, FOFS(targetname), ent->target))) { /* doors fire area portals in a specific way */ if (!Q_stricmp(t->classname, "func_areaportal") && (!Q_stricmp(ent->classname, "func_door") || !Q_stricmp(ent->classname, "func_door_rotating"))) { continue; } if (t == ent) { PF_dprintf("WARNING: Entity used itself.\n"); } else { if (t->use) { t->use(t, ent, activator); } } if (!ent->inuse) { PF_dprintf("entity was removed while using targets\n"); return; } } } }
void SV_PostprocessFrame() { edict_t *ent; int e, i; client_t *cl; guard(SV_PostprocessFrame); for (e = 0; e < ge->num_edicts; e++) { ent = EDICT_NUM(e); // ignore ents without visible models if (ent->svflags & SVF_NOCLIENT) continue; if (ent->s.event == EV_FOOTSTEP || ent->s.event == EV_FALLSHORT) { CVec3 point; point[0] = ent->s.origin[0]; point[1] = ent->s.origin[1]; point[2] = ent->s.origin[2] - 64; trace_t trace; SV_Trace(trace, ent->s.origin, point, ent->bounds, ent, MASK_PLAYERSOLID|MASK_MONSTERSOLID|MASK_WATER); if (trace.fraction < 1) { int footsteptype = trace.surface->material - 1; if (footsteptype < 0)//?? || footsteptype >= MATERIAL_COUNT) // i.e. MATERIAL_SILENT (== 0) or incorrect ent->s.event = 0; // EV_FOOTSTEP ? /* else if (footsteptype > MATERIAL_WATER) { //!! DEBUG !! (and hack) - should not happen developer->integer = 2; Com_DPrintf(S_RED"Bad material sound: idx=%d", footsteptype); ent->s.event = 0; } */ else if (ent->s.event == EV_FOOTSTEP) ent->s.event = EV_FOOTSTEP0 + footsteptype; else ent->s.event = EV_FALLSHORT0 + footsteptype; } } } // work only in deathmatch game, not in single-player or coop game if (sv_deathmatch->integer) //!! should be another variable; campersounds - below!! && sv_campersounds->integer) { unsigned t = appMilliseconds(); for (i = 0, cl = svs.clients; i < sv_maxclients->integer; i++, cl++) { if (cl->state != cs_spawned && cl->state != cs_connected) { cl->last_velocity2 = 0; continue; // dead / not connected player } ent = cl->edict; pmove_state_t *pm = &ent->client->ps.pmove; int prev_vel = cl->last_velocity2; int curr_vel = pm->velocity[2]; cl->last_velocity2 = curr_vel; if (cl->screaming && (curr_vel >= FALLING_SCREAM_VELOCITY1 || prev_vel >= FALLING_SCREAM_VELOCITY1 || pm->pm_type != PM_NORMAL)) // killed { // stop scream SV_StartSoundNew(NULL, ent, CHAN_BODY, SV_SoundIndex("*falling1.wav"), 0.0f, ATTN_NORM, 0); // volume=0 cl->screaming = false; } if (ent->s.event) continue; // have a sound event /* if (pm->pm_type == PM_SPECTATOR) //!! don't works - server doesn't send info about spectators (need another way) { sfxstate = 1; if (cl->sfxstate != sfxstate) { // just changed to spectator cl->sfxstate = sfxstate; cl->nextsfxtime = t + 1000 + (rand()&0x7FF); // ~1-3 sec. continue; } if (cl->nextsfxtime > t) continue; // waiting for sfx time cl->nextsfxtime = t + 1000 + (rand()&0x7FF); ent->s.event = EV_SPECTATOR0 + (rand()&3); appPrintf("%i:SPECT-SFX\n",i); } else*/ if (pm->pm_type == PM_NORMAL) { CVec3 pm_origin; pm_origin[0] = pm->origin[0] / 8.0f; pm_origin[1] = pm->origin[1] / 8.0f; pm_origin[2] = pm->origin[2] / 8.0f; // check for falling sounds if (!cl->screaming) { if (curr_vel < FALLING_SCREAM_VELOCITY1 && prev_vel < FALLING_SCREAM_VELOCITY1) { CVec3 end = pm_origin; end[2] = pm_origin[2] - FALLING_SCREAM_HEIGHT_WATER; trace_t trace; static const CBox bounds = {{-20, -20, -10}, {20, 20, 10}}; SV_Trace(trace, pm_origin, end, bounds, NULL, CONTENTS_WATER); if (trace.fraction == 1.0 && !trace.startsolid) // no water and start not in water { end[2] = pm_origin[2] - FALLING_SCREAM_HEIGHT_SOLID; SV_Trace(trace, pm_origin, end, bounds, NULL, CONTENTS_SOLID|CONTENTS_LAVA); if (trace.fraction == 1.0 || (!trace.ent && trace.plane.normal[2] < 0.5) || trace.contents & CONTENTS_LAVA || trace.surface->flags & SURF_SKY) cl->screaming = true; } } if (cl->screaming) { SV_StartSoundNew(NULL, ent, CHAN_BODY, SV_SoundIndex("*falling1.wav"), 1, ATTN_NORM, 0); continue; } } else if (curr_vel >= FALLING_SCREAM_VELOCITY1 || prev_vel >= FALLING_SCREAM_VELOCITY1) { // stop scream if (cl->screaming) SV_StartSoundNew(NULL, ent, CHAN_BODY, SV_SoundIndex("*falling1.wav"), 0.0, ATTN_NORM, 0); cl->screaming = false; } // check for idle (camper) sounds const CBspLeaf *leaf = CM_FindLeaf(pm_origin); int clust = leaf->cluster; int sfxstate = 2; if (!clust) continue; // possibly map without visinfo - no cluster partition (cannot detect campers with this way) if (clust != cl->lastcluster || cl->sfxstate != sfxstate || (leaf->contents & MASK_WATER)) { // changed cluster or state - not camping cl->sfxstate = sfxstate; cl->lastcluster = clust; cl->nextsfxtime = t + CAMPER_TIMEOUT + rand()%CAMPER_TIMEOUT_DELTA; continue; } if (cl->nextsfxtime > t) continue; // waiting for sfx time cl->nextsfxtime = t + CAMPER_REPEAT + rand()%CAMPER_REPEAT_DELTA; int sfx0, sfxn; if (pm->pm_flags & PMF_DUCKED) { sfx0 = EV_CAMPER0; sfxn = 2; } else { sfx0 = EV_CAMPER0+2; sfxn = 7; } ent->s.event = sfx0 + rand() % sfxn; } else { cl->sfxstate = 0; continue; } } } unguard; }
/*QUAKED worldspawn (0 0 0) ? * * Only used for the world. * "sky" environment map name * "skyaxis" vector axis for rotating sky * "skyrotate" speed of rotation in degrees/second * "sounds" music cd track number * "gravity" 800 is default gravity * "message" text to print at user logon */ void SP_worldspawn(edict_t *ent) { if (!ent) { return; } ent->movetype = MOVETYPE_PUSH; ent->solid = SOLID_BSP; ent->inuse = true; /* since the world doesn't use G_Spawn() */ ent->s.modelindex = 1; /* world model is always index 1 */ /* --------------- */ /* reserve some spots for dead player bodies for coop / deathmatch */ InitBodyQue(); /* set configstrings for items */ SetItemNames(); if (st.nextmap) { strcpy(level.nextmap, st.nextmap); } /* make some data visible to the server */ if (ent->message && ent->message[0]) { PF_Configstring(CS_NAME, ent->message); Q_strlcpy(level.level_name, ent->message, sizeof(level.level_name)); } else { Q_strlcpy(level.level_name, level.mapname, sizeof(level.level_name)); } if (st.sky && st.sky[0]) { PF_Configstring(CS_SKY, st.sky); } else { PF_Configstring(CS_SKY, "unit1_"); } PF_Configstring(CS_SKYROTATE, va("%f", st.skyrotate)); PF_Configstring(CS_SKYAXIS, va("%f %f %f", st.skyaxis[0], st.skyaxis[1], st.skyaxis[2])); PF_Configstring(CS_CDTRACK, va("%i", ent->sounds)); PF_Configstring(CS_MAXCLIENTS, va("%i", (int) (maxclients->value))); /* status bar program */ if (deathmatch->value) { PF_Configstring(CS_STATUSBAR, deathmatch_statusbar); } else { PF_Configstring(CS_STATUSBAR, singleplayer_statusbar); } /* --------------- */ level.pic_health = SV_ImageIndex("icon_health"); SV_ImageIndex("stat_flash"); if (!st.gravity) { Cvar_Set("sv_gravity", "800"); } else { Cvar_Set("sv_gravity", st.gravity); } snd_fry = SV_SoundIndex("player/fry.wav"); /* standing in lava / slime */ PrecacheItem(FindItem("Blaster")); SV_SoundIndex("player/lava1.wav"); SV_SoundIndex("player/lava2.wav"); SV_SoundIndex("misc/pc_up.wav"); SV_SoundIndex("misc/talk1.wav"); SV_SoundIndex("misc/udeath.wav"); /* gibs */ SV_SoundIndex("items/respawn1.wav"); /* sexed sounds */ SV_SoundIndex("*death1.wav"); SV_SoundIndex("*death2.wav"); SV_SoundIndex("*death3.wav"); SV_SoundIndex("*death4.wav"); SV_SoundIndex("*fall1.wav"); SV_SoundIndex("*fall2.wav"); SV_SoundIndex("*gurp1.wav"); /* drowning damage */ SV_SoundIndex("*gurp2.wav"); SV_SoundIndex("*jump1.wav"); /* player jump */ SV_SoundIndex("*pain25_1.wav"); SV_SoundIndex("*pain25_2.wav"); SV_SoundIndex("*pain50_1.wav"); SV_SoundIndex("*pain50_2.wav"); SV_SoundIndex("*pain75_1.wav"); SV_SoundIndex("*pain75_2.wav"); SV_SoundIndex("*pain100_1.wav"); SV_SoundIndex("*pain100_2.wav"); /* sexed models: THIS ORDER MUST MATCH THE DEFINES IN g_local.h you can add more, max 19 (pete change)these models are only loaded in coop or deathmatch. not singleplayer. */ if (coop->value || deathmatch->value) { SV_ModelIndex("#w_blaster.md2"); SV_ModelIndex("#w_shotgun.md2"); SV_ModelIndex("#w_sshotgun.md2"); SV_ModelIndex("#w_machinegun.md2"); SV_ModelIndex("#w_chaingun.md2"); SV_ModelIndex("#a_grenades.md2"); SV_ModelIndex("#w_glauncher.md2"); SV_ModelIndex("#w_rlauncher.md2"); SV_ModelIndex("#w_hyperblaster.md2"); SV_ModelIndex("#w_railgun.md2"); } /* ------------------- */ SV_SoundIndex("player/gasp1.wav"); /* gasping for air */ SV_SoundIndex("player/gasp2.wav"); /* head breaking surface, not gasping */ SV_SoundIndex("player/watr_in.wav"); /* feet hitting water */ SV_SoundIndex("player/watr_out.wav"); /* feet leaving water */ SV_SoundIndex("player/watr_un.wav"); /* head going underwater */ SV_SoundIndex("player/u_breath1.wav"); SV_SoundIndex("player/u_breath2.wav"); SV_SoundIndex("items/pkup.wav"); /* bonus item pickup */ SV_SoundIndex("world/land.wav"); /* landing thud */ SV_SoundIndex("misc/h2ohit1.wav"); /* landing splash */ SV_SoundIndex("items/damage.wav"); SV_SoundIndex("items/protect.wav"); SV_SoundIndex("items/protect4.wav"); SV_SoundIndex("weapons/noammo.wav"); SV_SoundIndex("infantry/inflies1.wav"); sm_meat_index = SV_ModelIndex("models/objects/gibs/sm_meat/tris.md2"); SV_ModelIndex("models/objects/gibs/arm/tris.md2"); SV_ModelIndex("models/objects/gibs/bone/tris.md2"); SV_ModelIndex("models/objects/gibs/bone2/tris.md2"); SV_ModelIndex("models/objects/gibs/chest/tris.md2"); SV_ModelIndex("models/objects/gibs/skull/tris.md2"); SV_ModelIndex("models/objects/gibs/head2/tris.md2"); /* Setup light animation tables. 'a' is total darkness, 'z' is doublebright. */ /* 0 normal */ PF_Configstring(CS_LIGHTS + 0, "m"); /* 1 FLICKER (first variety) */ PF_Configstring(CS_LIGHTS + 1, "mmnmmommommnonmmonqnmmo"); /* 2 SLOW STRONG PULSE */ PF_Configstring(CS_LIGHTS + 2, "abcdefghijklmnopqrstuvwxyzyxwvutsrqponmlkjihgfedcba"); /* 3 CANDLE (first variety) */ PF_Configstring(CS_LIGHTS + 3, "mmmmmaaaaammmmmaaaaaabcdefgabcdefg"); /* 4 FAST STROBE */ PF_Configstring(CS_LIGHTS + 4, "mamamamamama"); /* 5 GENTLE PULSE 1 */ PF_Configstring(CS_LIGHTS + 5, "jklmnopqrstuvwxyzyxwvutsrqponmlkj"); /* 6 FLICKER (second variety) */ PF_Configstring(CS_LIGHTS + 6, "nmonqnmomnmomomno"); /* 7 CANDLE (second variety) */ PF_Configstring(CS_LIGHTS + 7, "mmmaaaabcdefgmmmmaaaammmaamm"); /* 8 CANDLE (third variety) */ PF_Configstring(CS_LIGHTS + 8, "mmmaaammmaaammmabcdefaaaammmmabcdefmmmaaaa"); /* 9 SLOW STROBE (fourth variety) */ PF_Configstring(CS_LIGHTS + 9, "aaaaaaaazzzzzzzz"); /* 10 FLUORESCENT FLICKER */ PF_Configstring(CS_LIGHTS + 10, "mmamammmmammamamaaamammma"); /* 11 SLOW PULSE NOT FADE TO BLACK */ PF_Configstring(CS_LIGHTS + 11, "abcdefghijklmnopqrrqponmlkjihgfedcba"); /* styles 32-62 are assigned by the light program for switchable lights */ /* 63 testing */ PF_Configstring(CS_LIGHTS + 63, "a"); }
void Chaingun_Fire(edict_t *ent) { int i; int shots; vec3_t start; vec3_t forward, right, up; float r, u; vec3_t offset; int damage; int kick = 2; if (!ent) { return; } if (deathmatch->value) { damage = 6; } else { damage = 8; } if (ent->client->ps.gunframe == 5) { PF_StartSound(ent, CHAN_AUTO, SV_SoundIndex("weapons/chngnu1a.wav"), 1, ATTN_IDLE, 0); } if ((ent->client->ps.gunframe == 14) && !(ent->client->buttons & BUTTON_ATTACK)) { ent->client->ps.gunframe = 32; ent->client->weapon_sound = 0; return; } else if ((ent->client->ps.gunframe == 21) && (ent->client->buttons & BUTTON_ATTACK) && ent->client->pers.inventory[ent->client->ammo_index]) { ent->client->ps.gunframe = 15; } else { ent->client->ps.gunframe++; } if (ent->client->ps.gunframe == 22) { ent->client->weapon_sound = 0; PF_StartSound(ent, CHAN_AUTO, SV_SoundIndex("weapons/chngnd1a.wav"), 1, ATTN_IDLE, 0); } else { ent->client->weapon_sound = SV_SoundIndex("weapons/chngnl1a.wav"); } ent->client->anim_priority = ANIM_ATTACK; if (ent->client->ps.pmove.pm_flags & PMF_DUCKED) { ent->s.frame = FRAME_crattak1 - (ent->client->ps.gunframe & 1); ent->client->anim_end = FRAME_crattak9; } else { ent->s.frame = FRAME_attack1 - (ent->client->ps.gunframe & 1); ent->client->anim_end = FRAME_attack8; } if (ent->client->ps.gunframe <= 9) { shots = 1; } else if (ent->client->ps.gunframe <= 14) { if (ent->client->buttons & BUTTON_ATTACK) { shots = 2; } else { shots = 1; } } else { shots = 3; } if (ent->client->pers.inventory[ent->client->ammo_index] < shots) { shots = ent->client->pers.inventory[ent->client->ammo_index]; } if (!shots) { if (level.time >= ent->pain_debounce_time) { PF_StartSound(ent, CHAN_VOICE, SV_SoundIndex("weapons/noammo.wav"), 1, ATTN_NORM, 0); ent->pain_debounce_time = level.time + 1; } NoAmmoWeaponChange(ent); return; } for (i = 0; i < 3; i++) { ent->client->kick_origin[i] = crandom() * 0.35; ent->client->kick_angles[i] = crandom() * 0.7; } for (i = 0; i < shots; i++) { /* get start / end positions */ AngleVectors(ent->client->v_angle, forward, right, up); r = 7 + crandom() * 4; u = crandom() * 4; VectorSet(offset, 0, r, u + ent->viewheight - 8); P_ProjectSource(ent->client, ent->s.origin, offset, forward, right, start); fire_bullet(ent, start, forward, damage, kick, DEFAULT_BULLET_HSPREAD, DEFAULT_BULLET_VSPREAD, MOD_CHAINGUN); } /* send muzzle flash */ PF_WriteByte(svc_muzzleflash); PF_WriteShort(ent - g_edicts); PF_WriteByte(MZ_CHAINGUN1 + shots - 1); SV_Multicast(ent->s.origin, MULTICAST_PVS); PlayerNoise(ent, start, PNOISE_WEAPON); if (!((int) dmflags->value & DF_INFINITE_AMMO)) { ent->client->pers.inventory[ent->client->ammo_index] -= shots; } }
void Machinegun_Fire(edict_t *ent) { int i; vec3_t start; vec3_t forward, right; vec3_t angles; int damage = 8; int kick = 2; vec3_t offset; if (!ent) { return; } if (!(ent->client->buttons & BUTTON_ATTACK)) { ent->client->machinegun_shots = 0; ent->client->ps.gunframe++; return; } if (ent->client->ps.gunframe == 5) { ent->client->ps.gunframe = 4; } else { ent->client->ps.gunframe = 5; } if (ent->client->pers.inventory[ent->client->ammo_index] < 1) { ent->client->ps.gunframe = 6; if (level.time >= ent->pain_debounce_time) { PF_StartSound(ent, CHAN_VOICE, SV_SoundIndex("weapons/noammo.wav"), 1, ATTN_NORM, 0); ent->pain_debounce_time = level.time + 1; } NoAmmoWeaponChange(ent); return; } for (i = 1; i < 3; i++) { ent->client->kick_origin[i] = crandom() * 0.35; ent->client->kick_angles[i] = crandom() * 0.7; } ent->client->kick_origin[0] = crandom() * 0.35; ent->client->kick_angles[0] = ent->client->machinegun_shots * -1.5; /* raise the gun as it is firing */ if (!deathmatch->value) { ent->client->machinegun_shots++; if (ent->client->machinegun_shots > 9) { ent->client->machinegun_shots = 9; } } /* get start / end positions */ VectorAdd(ent->client->v_angle, ent->client->kick_angles, angles); AngleVectors(angles, forward, right, NULL); VectorSet(offset, 0, 8, ent->viewheight - 8); P_ProjectSource(ent->client, ent->s.origin, offset, forward, right, start); fire_bullet(ent, start, forward, damage, kick, DEFAULT_BULLET_HSPREAD, DEFAULT_BULLET_VSPREAD, MOD_MACHINEGUN); PF_WriteByte(svc_muzzleflash); PF_WriteShort(ent - g_edicts); PF_WriteByte(MZ_MACHINEGUN); SV_Multicast(ent->s.origin, MULTICAST_PVS); PlayerNoise(ent, start, PNOISE_WEAPON); if (!((int) dmflags->value & DF_INFINITE_AMMO)) { ent->client->pers.inventory[ent->client->ammo_index]--; } ent->client->anim_priority = ANIM_ATTACK; if (ent->client->ps.pmove.pm_flags & PMF_DUCKED) { ent->s.frame = FRAME_crattak1 - (int) (random() + 0.25); ent->client->anim_end = FRAME_crattak9; } else { ent->s.frame = FRAME_attack1 - (int) (random() + 0.25); ent->client->anim_end = FRAME_attack8; } }
void Weapon_HyperBlaster_Fire(edict_t *ent) { float rotation; vec3_t offset; int effect; int damage; if (!ent) { return; } ent->client->weapon_sound = SV_SoundIndex("weapons/hyprbl1a.wav"); if (!(ent->client->buttons & BUTTON_ATTACK)) { ent->client->ps.gunframe++; } else { if (!ent->client->pers.inventory[ent->client->ammo_index]) { if (level.time >= ent->pain_debounce_time) { PF_StartSound(ent, CHAN_VOICE, SV_SoundIndex("weapons/noammo.wav"), 1, ATTN_NORM, 0); ent->pain_debounce_time = level.time + 1; } NoAmmoWeaponChange(ent); } else { rotation = (ent->client->ps.gunframe - 5) * 2 * M_PI / 6; offset[0] = -4 * sin(rotation); offset[1] = 0; offset[2] = 4 * cos(rotation); if ((ent->client->ps.gunframe == 6) || (ent->client->ps.gunframe == 9)) { effect = EF_HYPERBLASTER; } else { effect = 0; } if (deathmatch->value) { damage = 15; } else { damage = 20; } Blaster_Fire(ent, offset, damage, true, effect); if (!((int) dmflags->value & DF_INFINITE_AMMO)) { ent->client->pers.inventory[ent->client->ammo_index]--; } ent->client->anim_priority = ANIM_ATTACK; if (ent->client->ps.pmove.pm_flags & PMF_DUCKED) { ent->s.frame = FRAME_crattak1 - 1; ent->client->anim_end = FRAME_crattak9; } else { ent->s.frame = FRAME_attack1 - 1; ent->client->anim_end = FRAME_attack8; } } ent->client->ps.gunframe++; if ((ent->client->ps.gunframe == 12) && ent->client->pers.inventory[ent->client->ammo_index]) { ent->client->ps.gunframe = 6; } } if (ent->client->ps.gunframe == 12) { PF_StartSound(ent, CHAN_AUTO, SV_SoundIndex("weapons/hyprbd1a.wav"), 1, ATTN_NORM, 0); ent->client->weapon_sound = 0; } }
void Weapon_Grenade(edict_t *ent) { if (!ent) { return; } if ((ent->client->newweapon) && (ent->client->weaponstate == WEAPON_READY)) { ChangeWeapon(ent); return; } if (ent->client->weaponstate == WEAPON_ACTIVATING) { ent->client->weaponstate = WEAPON_READY; ent->client->ps.gunframe = 16; return; } if (ent->client->weaponstate == WEAPON_READY) { if (((ent->client->latched_buttons | ent->client->buttons) & BUTTON_ATTACK)) { ent->client->latched_buttons &= ~BUTTON_ATTACK; if (ent->client->pers.inventory[ent->client->ammo_index]) { ent->client->ps.gunframe = 1; ent->client->weaponstate = WEAPON_FIRING; ent->client->grenade_time = 0; } else { if (level.time >= ent->pain_debounce_time) { PF_StartSound(ent, CHAN_VOICE, SV_SoundIndex("weapons/noammo.wav"), 1, ATTN_NORM, 0); ent->pain_debounce_time = level.time + 1; } NoAmmoWeaponChange(ent); } return; } if ((ent->client->ps.gunframe == 29) || (ent->client->ps.gunframe == 34) || (ent->client->ps.gunframe == 39) || (ent->client->ps.gunframe == 48)) { if (randk() & 15) { return; } } if (++ent->client->ps.gunframe > 48) { ent->client->ps.gunframe = 16; } return; } if (ent->client->weaponstate == WEAPON_FIRING) { if (ent->client->ps.gunframe == 5) { PF_StartSound(ent, CHAN_WEAPON, SV_SoundIndex("weapons/hgrena1b.wav"), 1, ATTN_NORM, 0); } if (ent->client->ps.gunframe == 11) { if (!ent->client->grenade_time) { ent->client->grenade_time = level.time + GRENADE_TIMER + 0.2; ent->client->weapon_sound = SV_SoundIndex("weapons/hgrenc1b.wav"); } /* they waited too long, detonate it in their hand */ if (!ent->client->grenade_blew_up && (level.time >= ent->client->grenade_time)) { ent->client->weapon_sound = 0; weapon_grenade_fire(ent, true); ent->client->grenade_blew_up = true; } if (ent->client->buttons & BUTTON_ATTACK) { return; } if (ent->client->grenade_blew_up) { if (level.time >= ent->client->grenade_time) { ent->client->ps.gunframe = 15; ent->client->grenade_blew_up = false; } else { return; } } } if (ent->client->ps.gunframe == 12) { ent->client->weapon_sound = 0; weapon_grenade_fire(ent, false); } if ((ent->client->ps.gunframe == 15) && (level.time < ent->client->grenade_time)) { return; } ent->client->ps.gunframe++; if (ent->client->ps.gunframe == 16) { ent->client->grenade_time = 0; ent->client->weaponstate = WEAPON_READY; } } }
/* * A generic function to handle * the basics of weapon thinking */ void Weapon_Generic(edict_t *ent, int FRAME_ACTIVATE_LAST, int FRAME_FIRE_LAST, int FRAME_IDLE_LAST, int FRAME_DEACTIVATE_LAST, int *pause_frames, int *fire_frames, void (*fire)(edict_t *ent)) { int n; if (!ent || !fire_frames || !fire) { return; } if (ent->deadflag || (ent->s.modelindex != 255)) /* VWep animations screw up corpses */ { return; } if (ent->client->weaponstate == WEAPON_DROPPING) { if (ent->client->ps.gunframe == FRAME_DEACTIVATE_LAST) { ChangeWeapon(ent); return; } else if ((FRAME_DEACTIVATE_LAST - ent->client->ps.gunframe) == 4) { ent->client->anim_priority = ANIM_REVERSE; if (ent->client->ps.pmove.pm_flags & PMF_DUCKED) { ent->s.frame = FRAME_crpain4 + 1; ent->client->anim_end = FRAME_crpain1; } else { ent->s.frame = FRAME_pain304 + 1; ent->client->anim_end = FRAME_pain301; } } ent->client->ps.gunframe++; return; } if (ent->client->weaponstate == WEAPON_ACTIVATING) { if (ent->client->ps.gunframe == FRAME_ACTIVATE_LAST) { ent->client->weaponstate = WEAPON_READY; ent->client->ps.gunframe = FRAME_IDLE_FIRST; return; } ent->client->ps.gunframe++; return; } if ((ent->client->newweapon) && (ent->client->weaponstate != WEAPON_FIRING)) { ent->client->weaponstate = WEAPON_DROPPING; ent->client->ps.gunframe = FRAME_DEACTIVATE_FIRST; if ((FRAME_DEACTIVATE_LAST - FRAME_DEACTIVATE_FIRST) < 4) { ent->client->anim_priority = ANIM_REVERSE; if (ent->client->ps.pmove.pm_flags & PMF_DUCKED) { ent->s.frame = FRAME_crpain4 + 1; ent->client->anim_end = FRAME_crpain1; } else { ent->s.frame = FRAME_pain304 + 1; ent->client->anim_end = FRAME_pain301; } } return; } if (ent->client->weaponstate == WEAPON_READY) { if (((ent->client->latched_buttons | ent->client->buttons) & BUTTON_ATTACK)) { ent->client->latched_buttons &= ~BUTTON_ATTACK; if ((!ent->client->ammo_index) || (ent->client->pers.inventory[ent->client->ammo_index] >= ent->client->pers.weapon->quantity)) { ent->client->ps.gunframe = FRAME_FIRE_FIRST; ent->client->weaponstate = WEAPON_FIRING; /* start the animation */ ent->client->anim_priority = ANIM_ATTACK; if (ent->client->ps.pmove.pm_flags & PMF_DUCKED) { ent->s.frame = FRAME_crattak1 - 1; ent->client->anim_end = FRAME_crattak9; } else { ent->s.frame = FRAME_attack1 - 1; ent->client->anim_end = FRAME_attack8; } } else { if (level.time >= ent->pain_debounce_time) { PF_StartSound(ent, CHAN_VOICE, SV_SoundIndex("weapons/noammo.wav"), 1, ATTN_NORM, 0); ent->pain_debounce_time = level.time + 1; } NoAmmoWeaponChange(ent); } } else { if (ent->client->ps.gunframe == FRAME_IDLE_LAST) { ent->client->ps.gunframe = FRAME_IDLE_FIRST; return; } if (pause_frames) { for (n = 0; pause_frames[n]; n++) { if (ent->client->ps.gunframe == pause_frames[n]) { if (randk() & 15) { return; } } } } ent->client->ps.gunframe++; return; } } if (ent->client->weaponstate == WEAPON_FIRING) { for (n = 0; fire_frames[n]; n++) { if (ent->client->ps.gunframe == fire_frames[n]) { fire(ent); break; } } if (!fire_frames[n]) { ent->client->ps.gunframe++; } if (ent->client->ps.gunframe == FRAME_IDLE_FIRST + 1) { ent->client->weaponstate = WEAPON_READY; } } }