示例#1
0
void target_earthquake_think (edict_t *self)
{
	int		i;
	edict_t	*e;

	if (self->pain_debounce_framenum < level.framenum)
	{
		gi.positioned_sound (self->s.origin, self, CHAN_AUTO, self->noise_index, 1.0f, ATTN_NONE, 0);
		self->pain_debounce_framenum = level.framenum + SECS_TO_FRAMES(0.5f);
	}

	for (i=1, e=g_edicts+i; i < globals.num_edicts; i++,e++)
	{
		if (!e->inuse)
			continue;
		if (!e->client)
			continue;
		if (!e->groundentity)
			continue;

		e->groundentity = NULL;
		e->velocity[0] += crandom()* 150;
		e->velocity[1] += crandom()* 150;
		e->velocity[2] = self->speed * (100.0f / e->mass);
	}

	if (level.framenum < self->damage_debounce_framenum)
		self->nextthink = level.framenum + SECS_TO_FRAMES(0.1f);
}
示例#2
0
void target_earthquake_use (edict_t *self, edict_t *other, edict_t *activator)
{
	self->damage_debounce_framenum = level.framenum + SECS_TO_FRAMES(self->count);
	self->nextthink = level.framenum + SECS_TO_FRAMES(0.1f);
	self->activator = activator;
	self->pain_debounce_framenum = 0;
}
示例#3
0
/**
 * Resend the entire statusbar string to update the hud.
 *
 */
void TDM_UpdateHud(edict_t *ent, qboolean force) {

	if (!ent->client)
		return;

	if (!force) {
		if (g_weapon_hud->value == 0) {
			return;
		}

		if (!ent->client->next_hud_update) {
			return;
		}

		// too soon, can only send statusbar at most once every 2 seconds
		if ((level.framenum - ent->client->last_hud_update) < SECS_TO_FRAMES(2.0F)) {
			return;
		}

		// not time yet
		if (ent->client->next_hud_update > level.framenum) {
			return;
		}
	}

	if (ent->client->pers.team == TEAM_SPEC) {
		TDM_SendSpectatorStatusBar(ent);
	} else if (ent->client->pers.team > TEAM_SPEC) {
		TDM_SendPlayerStatusBar(ent);
	}

	// set next update to way in the future so it's basically never automatically updated.
	ent->client->next_hud_update = 0;
	ent->client->last_hud_update = level.framenum;
}
示例#4
0
void hurt_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
{
	int		dflags;

	if (!other->takedamage)
		return;

	if (self->touch_debounce_framenum > level.framenum)
		return;

	if (self->spawnflags & 16)
		self->touch_debounce_framenum = level.framenum + SECS_TO_FRAMES(1);
	else
		self->touch_debounce_framenum = level.framenum + 1;

	if (!(self->spawnflags & 4))
	{
		if ((level.framenum % 10) == 0)
			gi.sound (other, CHAN_AUTO, self->noise_index, 1, ATTN_NORM, 0);
	}

	if (self->spawnflags & 8)
		dflags = DAMAGE_NO_PROTECTION;
	else
		dflags = 0;
	T_Damage (other, self, self, vec3_origin, other->s.origin, vec3_origin, self->dmg, self->dmg, dflags, MOD_TRIGGER_HURT);
}
示例#5
0
void SP_target_crosslevel_target (edict_t *self)
{
	if (! self->delay)
		self->delay = 1;
	self->svflags = SVF_NOCLIENT;

	self->think = target_crosslevel_target_think;
	self->nextthink = level.framenum + SECS_TO_FRAMES(self->delay);
}
示例#6
0
void weapon_grenade_fire (edict_t *ent, qboolean held)
{
	vec3_t	offset;
	vec3_t	forward, right;
	vec3_t	start;
	int		damage = 125;
	float	timer;
	int		speed;
	float	radius;

	radius = damage+40;

	if (is_quad)
	{
		//r1: prevent quad on someone making grenades into quad grenades on death explode
		if (is_quad == ent || g_bugs->value >= 1)
			damage *= 4;
	}

	VectorSet(offset, 8, 8, ent->viewheight-8);
	AngleVectors (ent->client->v_angle, forward, right, NULL);
	P_ProjectSource (ent->client, ent->s.origin, offset, forward, right, start);

	timer = (ent->client->grenade_framenum - level.framenum) * FRAMETIME;
	speed = GRENADE_MINSPEED + (GRENADE_TIMER - timer) * ((GRENADE_MAXSPEED - GRENADE_MINSPEED) / GRENADE_TIMER);
	fire_grenade2 (ent, start, forward, damage, speed, timer, radius, held);
	TDM_WeaponFired (ent);

	if (! ( (int)dmflags->value & DF_INFINITE_AMMO ) )
		ent->client->inventory[ent->client->ammo_index]--;

	ent->client->grenade_framenum = level.framenum + SECS_TO_FRAMES(1);

	if(ent->deadflag || ent->s.modelindex != 255) // VWep animations screw up corpses
	{
		return;
	}

	if (ent->health <= 0)
		return;

	if (ent->client->ps.pmove.pm_flags & PMF_DUCKED)
	{
		ent->client->anim_priority = ANIM_ATTACK;
		ent->s.frame = FRAME_crattak1-1;
		ent->client->anim_end = FRAME_crattak3;
	}
	else
	{
		ent->client->anim_priority = ANIM_REVERSE;
		ent->s.frame = FRAME_wave08;
		ent->client->anim_end = FRAME_wave01;
	}
}
示例#7
0
void use_target_explosion (edict_t *self, edict_t *other, edict_t *activator)
{
	self->activator = activator;

	if (!self->delay)
	{
		target_explosion_explode (self);
		return;
	}

	self->think = target_explosion_explode;
	self->nextthink = level.framenum + SECS_TO_FRAMES(self->delay);
}
示例#8
0
// the trigger was just activated
// ent->activator should be set to the activator so it can be held through a delay
// so wait for the delay time before firing
void multi_trigger (edict_t *ent)
{
	if (ent->nextthink)
		return;		// already been triggered

	G_UseTargets (ent, ent->activator);

	if (ent->wait > 0)	
	{
		ent->think = multi_wait;
		ent->nextthink = level.framenum + SECS_TO_FRAMES(ent->wait);
	}
	else
	{	// we can't just remove (self) here, because this is a touch function
		// called while looping through area links...
		ent->touch = NULL;
		ent->nextthink = level.framenum + 1;
		ent->think = G_FreeEdict;
	}
}
示例#9
0
/*
=================
Think_Weapon

Called by ClientBeginServerFrame and ClientThink
=================
*/
void Think_Weapon (edict_t *ent)
{
	// if just died, put the weapon away
	if (ent->health < 1)
	{
		ent->client->newweapon = NULL;
		ChangeWeapon (ent);
	}

	// don't run weapons at all during timeout, preserve reload frame etc
	if (tdm_match_status == MM_TIMEOUT)
		return;

	//r1: don't allow any attack during countdown
	if (tdm_match_status == MM_COUNTDOWN)
	{
		ent->client->buttons &= ~BUTTON_ATTACK;
		ent->client->latched_buttons &= ~BUTTON_ATTACK;
	}

	// variable FPS support
	if (ent->client->next_weapon_think > level.framenum)
		return;

	ent->client->next_weapon_think = level.framenum + (SECS_TO_FRAMES(0.1f));

	// call active weapon think routine
	if (ent->client->weapon && ent->client->weapon->weaponthink)
	{
		if (ent->client->quad_framenum > level.framenum)
			is_quad = ent;
		else
			is_quad = NULL;

		if (ent->client->silencer_shots)
			is_silenced = MZ_SILENCED;
		else
			is_silenced = 0;
		ent->client->weapon->weaponthink (ent);
	}
}
示例#10
0
void trigger_push_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
{
	if (other->enttype == ENT_GRENADE)
	{
		VectorScale (self->movedir, self->speed * 10, other->velocity);
	}
	else if (other->health > 0)
	{
		VectorScale (self->movedir, self->speed * 10, other->velocity);

		if (other->client)
		{
			// don't take falling damage immediately from this
			VectorCopy (other->velocity, other->client->oldvelocity);
			if (other->fly_sound_debounce_framenum < level.framenum)
			{
				other->fly_sound_debounce_framenum = level.framenum + SECS_TO_FRAMES(1.5f);
				gi.sound (other, CHAN_AUTO, windsound, 1, ATTN_NORM, 0);
			}
		}
	}
	if (self->spawnflags & PUSH_ONCE)
		G_FreeEdict (self);
}
示例#11
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->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->inventory[ent->client->ammo_index] < 1)
	{
		ent->client->ps.gunframe = 6;
		if (level.framenum >= ent->pain_debounce_framenum)
		{
			gi.sound(ent, CHAN_VOICE, gi.soundindex("weapons/noammo.wav"), 1, ATTN_NORM, 0);
			ent->pain_debounce_framenum = level.framenum + SECS_TO_FRAMES(1);
		}
		NoAmmoWeaponChange (ent);
		return;
	}

	if (is_quad == ent)
	{
		damage *= 4;
		kick *= 4;
	}

	for (i=1 ; i<3 ; i++)
	{
		ent->client->kick_origin_final[i] = crandom() * 0.35f;
		ent->client->kick_angles_final[i] = crandom() * 0.7f;
	}
	ent->client->kick_origin_final[0] = crandom() * 0.35f;
	ent->client->kick_angles_final[0] = ent->client->machinegun_shots * -1.5f;

	ent->client->kick_origin_start = 0;
	ent->client->kick_origin_end = 0.1f * SERVER_FPS;

	// get start / end positions
	VectorAdd (ent->client->v_angle, ent->client->kick_angles_final, 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);
	TDM_WeaponFired (ent);

	gi.WriteByte (svc_muzzleflash);
	gi.WriteShort (ent-g_edicts);
	gi.WriteByte (MZ_MACHINEGUN | is_silenced);
	gi.multicast (ent->s.origin, MULTICAST_PVS);

	if (! ( (int)dmflags->value & DF_INFINITE_AMMO ) )
		ent->client->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.25f);
		ent->client->anim_end = FRAME_crattak9;
	}
	else
	{
		ent->s.frame = FRAME_attack1 - (int) (random()+0.25f);
		ent->client->anim_end = FRAME_attack8;
	}
}
示例#12
0
void Weapon_Grenade (edict_t *ent)
{
	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->inventory[ent->client->ammo_index])
			{
				ent->client->ps.gunframe = 1;
				ent->client->weaponstate = WEAPON_FIRING;
				ent->client->grenade_framenum = 0;
			}
			else
			{
				if (level.framenum >= ent->pain_debounce_framenum)
				{
					gi.sound(ent, CHAN_VOICE, gi.soundindex("weapons/noammo.wav"), 1, ATTN_NORM, 0);
					ent->pain_debounce_framenum = level.framenum + SECS_TO_FRAMES(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 (genrand_int32()&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)
			gi.sound(ent, CHAN_WEAPON, gi.soundindex("weapons/hgrena1b.wav"), 1, ATTN_NORM, 0);

		if (ent->client->ps.gunframe == 11)
		{
			if (!ent->client->grenade_framenum)
			{
				ent->client->grenade_framenum = level.framenum + SECS_TO_FRAMES(GRENADE_TIMER + 0.2f);
				ent->client->weapon_sound = gi.soundindex("weapons/hgrenc1b.wav");
			}

			// they waited too long, detonate it in their hand
			if (ent->client->grenade_state != GRENADE_BLEW_UP && level.framenum >= ent->client->grenade_framenum)
			{
				ent->client->weapon_sound = 0;
				weapon_grenade_fire (ent, true);
				ent->client->grenade_state = GRENADE_BLEW_UP;
			}

			if (ent->client->buttons & BUTTON_ATTACK)
				return;

			if (ent->client->grenade_state == GRENADE_BLEW_UP)
			{
				if (level.framenum >= ent->client->grenade_framenum)
				{
					ent->client->ps.gunframe = 15;
					ent->client->grenade_state = GRENADE_NONE;
				}
				else
				{
					return;
				}
			}
		}

		if (ent->client->ps.gunframe == 12)
		{
			ent->client->weapon_sound = 0;
			weapon_grenade_fire (ent, false);
			ent->client->grenade_state = GRENADE_THROWN;
		}

		if ((ent->client->ps.gunframe == 15) && (level.framenum < ent->client->grenade_framenum))
			return;

		ent->client->ps.gunframe++;

		if (ent->client->ps.gunframe == 16)
		{
			ent->client->grenade_framenum = 0;
			ent->client->grenade_state = GRENADE_NONE;
			ent->client->weaponstate = WEAPON_READY;
		}
	}
}
示例#13
0
void Weapon_HyperBlaster_Fire (edict_t *ent)
{
	float	rotation;
	vec3_t	offset;
	int		effect;
	int		damage;

	ent->client->weapon_sound = gi.soundindex("weapons/hyprbl1a.wav");

	if (!(ent->client->buttons & BUTTON_ATTACK))
	{
		ent->client->ps.gunframe++;
	}
	else
	{
		if (! ent->client->inventory[ent->client->ammo_index] )
		{
			if (level.framenum >= ent->pain_debounce_framenum)
			{
				gi.sound(ent, CHAN_VOICE, gi.soundindex("weapons/noammo.wav"), 1, ATTN_NORM, 0);
				ent->pain_debounce_framenum = level.framenum + SECS_TO_FRAMES(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;

			damage = 15;

			Blaster_Fire (ent, offset, damage, true, effect);
			TDM_WeaponFired (ent);

			if (! ( (int)dmflags->value & DF_INFINITE_AMMO ) )
				ent->client->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->inventory[ent->client->ammo_index])
			ent->client->ps.gunframe = 6;
	}

	if (ent->client->ps.gunframe == 12)
	{
		gi.sound(ent, CHAN_AUTO, gi.soundindex("weapons/hyprbd1a.wav"), 1, ATTN_NORM, 0);
		ent->client->weapon_sound = 0;
	}

}
示例#14
0
/*
==============
TDM_Disconnected
==============
A player disconnected, do things.
*/
void TDM_Disconnected (edict_t *ent)
{
	qboolean	removeTimeout;

	removeTimeout = false;

	//have to check this right up here since we nuke the teamplayer just below!
	if (tdm_match_status == MM_TIMEOUT && level.tdm_timeout_caller && level.tdm_timeout_caller->client == ent)
		removeTimeout = true;

	//we remove this up here so TDM_LeftTeam doesn't try to resume if we become implicit timeout caller
	TDM_RemoveStatsLink (ent);

	if (ent->client->pers.team)
	{
		if (tdm_match_status >= MM_PLAYING && tdm_match_status != MM_SCOREBOARD)
		{
			//do joincode stuff if a team player disconnects - save all their client info
			ent->client->resp.teamplayerinfo->saved_client = gi.TagMalloc (sizeof(gclient_t), TAG_GAME);
			*ent->client->resp.teamplayerinfo->saved_client = *ent->client;

			ent->client->resp.teamplayerinfo->saved_entity = gi.TagMalloc (sizeof(edict_t), TAG_GAME);
			*ent->client->resp.teamplayerinfo->saved_entity = *ent;

			if (TDM_Is1V1() && g_1v1_timeout->value > 0)
			{
				edict_t		*ghost;

				//may have already been set by a player or previous client disconnect
				if (tdm_match_status != MM_TIMEOUT)
				{	
					edict_t		*opponent;

					//timeout is called implicitly in 1v1 games or the other player would auto win
					level.timeout_end_framenum = level.realframenum + SECS_TO_FRAMES(g_1v1_timeout->value);
					level.last_tdm_match_status = tdm_match_status;
					tdm_match_status = MM_TIMEOUT;

					level.tdm_timeout_caller = ent->client->resp.teamplayerinfo;
					gi.bprintf (PRINT_CHAT, "%s disconnected and has %s to reconnect.\n", level.tdm_timeout_caller->name, TDM_SecsToString (g_1v1_timeout->value));

					//show the opponent their options
					opponent = TDM_FindPlayerForTeam (TEAM_A);
					if (opponent)
						gi.cprintf (opponent, PRINT_HIGH, "Your opponent has disconnected. You can allow them %s to reconnect, or you can force a forfeit by typing 'win' in the console.\n", TDM_SecsToString (g_1v1_timeout->value));

					opponent = TDM_FindPlayerForTeam (TEAM_B);
					if (opponent)
						gi.cprintf (opponent, PRINT_HIGH, "Your opponent has disconnected. You can allow them %s to reconnect, or you can force a forfeit by typing 'win' in the console.\n", TDM_SecsToString (g_1v1_timeout->value));
				}

				//show a "ghost" player where the player was
				ghost = G_Spawn ();
				VectorCopy (ent->s.origin, ghost->s.origin);
				VectorCopy (ent->s.origin, ghost->old_origin);
				VectorCopy (ent->s.angles, ghost->s.angles);
				ghost->s.effects = EF_SPHERETRANS;
				ghost->s.modelindex = 255;
				ghost->s.modelindex2 = 255;
				ghost->s.skinnum = ent - g_edicts - 1;
				ghost->s.frame = ent->s.frame;
				ghost->count = ent->s.number;
				ghost->classname = "ghost";
				ghost->target_ent = ent;
				ghost->enttype = ENT_GHOST;
				gi.linkentity (ghost);
			}
		}

		if (removeTimeout)
			TDM_ResumeGame ();

		TDM_LeftTeam (ent, false);
	}

	TDM_TeamsChanged ();

	if (tdm_match_status == MM_WARMUP && teaminfo[TEAM_SPEC].players == 0 && teaminfo[TEAM_A].players == 0 && teaminfo[TEAM_B].players == 0)
	{
		if (vote.active)
			TDM_RemoveVote ();

		//reset the map if it's been running for over 7 days to workaround time precision bugs in the engine, fixes 0000208
		if (time (NULL) - level.spawntime > (86400 * 7))
		{
			char	command[256];
			Com_sprintf (command, sizeof(command), "gamemap \"%s\"\n", level.mapname);
			gi.AddCommandString (command);
		}
	}
	else
		TDM_CheckVote ();

	//zero for connecting clients on server browsers
	ent->client->ps.stats[STAT_FRAGS] = 0;
}
示例#15
0
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->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 (g_fast_weap_switch->value >= 2)
			ent->client->ps.gunframe = FRAME_ACTIVATE_LAST;

		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;

		if (g_fast_weap_switch->value >= 1)
		{
			ChangeWeapon (ent);
			return;
		}
		else
			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->inventory[ent->client->ammo_index] >= ent->client->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.framenum >= ent->pain_debounce_framenum)
				{
					gi.sound(ent, CHAN_VOICE, gi.soundindex("weapons/noammo.wav"), 1, ATTN_NORM, 0);
					ent->pain_debounce_framenum = level.framenum + SECS_TO_FRAMES(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 (genrand_int32()&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])
			{
				if (ent->client->quad_framenum > level.framenum)
					gi.sound(ent, CHAN_ITEM, gi.soundindex("items/damage3.wav"), 1, ATTN_NORM, 0);

				fire (ent);
				break;
			}
		}

		if (!fire_frames[n])
		{
			ent->client->ps.gunframe++;

			if ((ent->client->newweapon) && g_fast_weap_switch->value >= 3)
			{
				ChangeWeapon (ent);
				return;
			}
		}
		else
		{
			if ((ent->client->newweapon) && g_fast_weap_switch->value >= 4)
			{
				ChangeWeapon (ent);
				return;
			}
		}

		if (ent->client->ps.gunframe == FRAME_IDLE_FIRST+1)
			ent->client->weaponstate = WEAPON_READY;
	}
}
示例#16
0
void target_laser_think (edict_t *self)
{
	edict_t	*ignore;
	vec3_t	start;
	vec3_t	end;
	trace_t	tr;
	vec3_t	point;
	vec3_t	last_movedir;
	int		count;

	if (self->spawnflags & 0x80000000)
		count = 8;
	else
		count = 4;

	if (self->enemy)
	{
		VectorCopy (self->movedir, last_movedir);
		VectorMA (self->enemy->absmin, 0.5f, self->enemy->size, point);
		VectorSubtract (point, self->s.origin, self->movedir);
		VectorNormalize (self->movedir);
		if (!VectorCompare(self->movedir, last_movedir))
			self->spawnflags |= 0x80000000;
	}

	ignore = self;
	VectorCopy (self->s.origin, start);
	VectorMA (start, 2048, self->movedir, end);
	while(1)
	{
		tr = gi.trace (start, NULL, NULL, end, ignore, CONTENTS_SOLID|CONTENTS_MONSTER|CONTENTS_DEADMONSTER);

		if (!tr.ent)
			break;

		// hurt it if we can
		if ((tr.ent->takedamage) && !(tr.ent->flags & FL_IMMUNE_LASER))
			T_Damage (tr.ent, self, self->activator, self->movedir, tr.endpos, vec3_origin, self->dmg, 1, DAMAGE_ENERGY, MOD_TARGET_LASER);

		// if we hit something that's not a monster or player or is immune to lasers, we're done
		if (!(tr.ent->svflags & SVF_MONSTER) && (!tr.ent->client))
		{
			if (self->spawnflags & 0x80000000)
			{
				self->spawnflags &= ~0x80000000;
				gi.WriteByte (svc_temp_entity);
				gi.WriteByte (TE_LASER_SPARKS);
				gi.WriteByte (count);
				gi.WritePosition (tr.endpos);
				gi.WriteDir (tr.plane.normal);
				gi.WriteByte (self->s.skinnum & 255);
				gi.multicast (tr.endpos, MULTICAST_PVS);
			}
			break;
		}

		ignore = tr.ent;
		VectorCopy (tr.endpos, start);
	}

	VectorCopy (tr.endpos, self->s.old_origin);

	self->nextthink = level.framenum + SECS_TO_FRAMES(0.1f);
}
示例#17
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;

	damage = 6;

	if (ent->client->ps.gunframe == 5)
		gi.sound(ent, CHAN_AUTO, gi.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->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;
		gi.sound(ent, CHAN_AUTO, gi.soundindex("weapons/chngnd1a.wav"), 1, ATTN_IDLE, 0);
	}
	else
	{
		ent->client->weapon_sound = gi.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->inventory[ent->client->ammo_index] < shots)
		shots = ent->client->inventory[ent->client->ammo_index];

	if (!shots)
	{
		if (level.framenum >= ent->pain_debounce_framenum)
		{
			gi.sound(ent, CHAN_VOICE, gi.soundindex("weapons/noammo.wav"), 1, ATTN_NORM, 0);
			ent->pain_debounce_framenum = level.framenum + SECS_TO_FRAMES(1);
		}
		NoAmmoWeaponChange (ent);
		return;
	}

	if (is_quad == ent)
	{
		damage *= 4;
		kick *= 4;
	}

	for (i=0 ; i<3 ; i++)
	{
		ent->client->kick_origin_final[i] = crandom() * 0.35f;
		ent->client->kick_angles_final[i] = crandom() * 0.7f;
	}

	ent->client->kick_origin_start = 0;
	ent->client->kick_origin_end = 0.1f * SERVER_FPS;

	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);
		TDM_WeaponFired (ent);
	}

	// send muzzle flash
	gi.WriteByte (svc_muzzleflash);
	gi.WriteShort (ent-g_edicts);
	gi.WriteByte ((MZ_CHAINGUN1 + shots - 1) | is_silenced);
	gi.multicast (ent->s.origin, MULTICAST_PVS);

	if (! ( (int)dmflags->value & DF_INFINITE_AMMO ) )
		ent->client->inventory[ent->client->ammo_index] -= shots;
}
示例#18
0
void SP_target_laser (edict_t *self)
{
	// let everything else get spawned before we start firing
	self->think = target_laser_start;
	self->nextthink = level.framenum + SECS_TO_FRAMES(1);
}