Beispiel #1
0
/*
===============
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++;
	}
}
Beispiel #2
0
/*
 * 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;
      }
    }
  }
}
Beispiel #3
0
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;
}
Beispiel #4
0
/*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");
}
Beispiel #5
0
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;
  }
}
Beispiel #6
0
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;
  }
}
Beispiel #7
0
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;
  }
}
Beispiel #8
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;
    }
  }
}
Beispiel #9
0
/*
 * 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;
    }
  }
}