예제 #1
0
파일: weapon.c 프로젝트: greck2908/qengine
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;
  }
}
예제 #2
0
void
fire_rail(edict_t *self, vec3_t start, vec3_t aimdir, int damage, int kick)
{
	vec3_t from;
	vec3_t end;
	trace_t tr;
	edict_t *ignore;
	int mask;
	qboolean water;

	if (!self)
	{
		return;
	}

	VectorMA(start, 8192, aimdir, end);
	VectorCopy(start, from);
	ignore = self;
	water = false;
	mask = MASK_SHOT | CONTENTS_SLIME | CONTENTS_LAVA;

	while (ignore)
	{
		tr = gi.trace(from, NULL, NULL, end, ignore, mask);

		if (tr.contents & (CONTENTS_SLIME | CONTENTS_LAVA))
		{
			mask &= ~(CONTENTS_SLIME | CONTENTS_LAVA);
			water = true;
		}
		else
		{
			if ((tr.ent->svflags & SVF_MONSTER) || (tr.ent->client) ||
				(tr.ent->solid == SOLID_BBOX))
			{
				ignore = tr.ent;
			}
			else
			{
				ignore = NULL;
			}

			if ((tr.ent != self) && (tr.ent->takedamage))
			{
				T_Damage(tr.ent, self, self, aimdir, tr.endpos, tr.plane.normal,
						damage, kick, 0, MOD_RAILGUN);
			}
			else
			{
				ignore = NULL;
			}
		}

		VectorCopy(tr.endpos, from);
	}

	/* send gun puff / flash */
	gi.WriteByte(svc_temp_entity);
	gi.WriteByte(TE_RAILTRAIL);
	gi.WritePosition(start);
	gi.WritePosition(tr.endpos);
	gi.multicast(self->s.origin, MULTICAST_PHS);

	if (water)
	{
		gi.WriteByte(svc_temp_entity);
		gi.WriteByte(TE_RAILTRAIL);
		gi.WritePosition(start);
		gi.WritePosition(tr.endpos);
		gi.multicast(tr.endpos, MULTICAST_PHS);
	}

	if (self->client)
	{
		PlayerNoise(self, tr.endpos, PNOISE_IMPACT);
	}
}
예제 #3
0
void weapon_supershotgun_fire (edict_t *ent)
{
	vec3_t		start;
	vec3_t		forward, right;
	vec3_t		offset;
	vec3_t		v;
	iteminfo_t *info = getWornItemInfo(ent, 0);
	int			damage;
	int			ammo;
	int			kick = 9;
	int			count = (info->arg4 + (int)(info->arg5 * ent->client->pers.skill[3])) / 2;

	damage = (int) ceil(info->arg1 + info->arg2 * (float) ent->client->pers.skill[1]) * 0.5; //(info->arg4 / 2));
	damage /= count;
//	damage = info->arg1 + (int) ceil(info->arg2 * ent->client->pers.skill[1]);

	AngleVectors (ent->client->v_angle, forward, right, NULL);

	VectorScale (forward, -2, ent->client->kick_origin);
	ent->client->kick_angles[0] = -2;

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

	damage = applyWeaponBonuses(ent, damage, count);
	if (is_quad)
		kick *= 4;

	v[PITCH] = ent->client->v_angle[PITCH];
	v[ROLL]  = ent->client->v_angle[ROLL];
	if (ent->client->ps.gunframe == 7) {
		v[YAW]   = ent->client->v_angle[YAW] - 5;
		AngleVectors (v, forward, NULL, NULL);
		fire_shotgun (ent, start, forward, damage, kick, info->arg6, info->arg6, count, MOD_SSHOTGUN);
		if (info->arg7 == 0) {
			v[YAW]   = ent->client->v_angle[YAW] + 5;
			AngleVectors (v, forward, NULL, NULL);
			fire_shotgun (ent, start, forward, damage, kick, info->arg6, info->arg6, count, MOD_SSHOTGUN);
		}
	} else {
		v[YAW]   = ent->client->v_angle[YAW] + 5;
		AngleVectors (v, forward, NULL, NULL);
		fire_shotgun (ent, start, forward, damage, kick, info->arg6, info->arg6, count, MOD_SSHOTGUN);
	}
	ent->client->silencer_shots-=3;

	// send muzzle flash
	if ((ent->client->silencer_shots > 0) && (ent->client->pers.skill[58] > 7)) {
		ent->client->silencer_shots -= 1;
	} else {
		gi.WriteByte (svc_muzzleflash);
		gi.WriteShort (ent-g_edicts);
		gi.WriteByte (MZ_SSHOTGUN | is_silenced);
		gi.multicast (ent->s.origin, MULTICAST_PVS);
	}

	ent->client->ps.gunframe++;
	PlayerNoise(ent, start, PNOISE_WEAPON);

//	if (! ( (int)dmflags->value & DF_INFINITE_AMMO ) ) {
		ammo = 1;
		if (info->arg7 == 0) {
			ammo = 2;
		}
		ent->client->pers.inventory[ent->client->ammo_index] -= ammo;
//	}
}
예제 #4
0
/*
=================
P_FallingDamage
=================
*/
void P_FallingDamage (edict_t *ent)
{
	float	delta;
	int		damage;
	vec3_t	dir;

	if (ent->s.modelindex != 255)
		return;		// not in the player model

	if (ent->movetype == MOVETYPE_NOCLIP)
		return;

	if ((ent->client->oldvelocity[2] < 0) && (ent->velocity[2] > ent->client->oldvelocity[2]) && (!ent->groundentity))
	{
		// if we are airborne and using double-jump, we shouldn't take damage
		//FIXME: why are we taking fall damage when we are in the air in the first place???
		if (ent->v_flags & SFLG_DOUBLEJUMP)
			return;

		delta = ent->client->oldvelocity[2];
	}
	else
	{
		if (!ent->groundentity)
			return;
		delta = ent->velocity[2] - ent->client->oldvelocity[2];
	}
	delta = delta*delta * 0.0001;

	//K03 Begin
	if (ent->client->thrusting)
		return;
	if (ent->client->hook_state == HOOK_ON)
        return;
	//K03 End

	// never take falling damage if completely underwater
	if (ent->waterlevel == 3)
		return;
	if (ent->waterlevel == 2)
		delta *= 0.25;
	if (ent->waterlevel == 1)
		delta *= 0.5;

	if (delta < 1)
		return;

	if (delta < 15)
	{
		if ((ent->client->pers.inventory[ITEM_INDEX(FindItem("Stealth Boots"))] < 1))
		{
			if((ent->myskills.abilities[CLOAK].disable) || (ent->myskills.abilities[CLOAK].current_level < 1))
			{
				// morphed players don't make footsteps
				if (!ent->mtype)
					ent->s.event = EV_FOOTSTEP;

				PlayerNoise(ent, ent->s.origin, PNOISE_SELF);	//ponko

				// if the player is not crouched, then alert monsters of footsteps
				if (!(ent->client->ps.pmove.pm_flags & PMF_DUCKED))
					ent->lastsound = level.framenum;
			}
		}
		return;
	}

	ent->client->fall_value = delta*0.5;
	if (ent->client->fall_value > 40)
		ent->client->fall_value = 40;
	ent->client->fall_time = level.time + FALL_TIME;

	if (delta > 30)
	{
		if (ent->health > 0)
		{
			if (delta >= 55)
				ent->s.event = EV_FALLFAR;
			else
				ent->s.event = EV_FALL;
			PlayerNoise(ent, ent->s.origin, PNOISE_SELF); //ponko
		}
		ent->pain_debounce_time = level.time;	// no normal pain sound
		damage = (delta-30)/2;
		if (damage < 1)
			damage = 1;
		VectorSet (dir, 0, 0, 1);

		if (!deathmatch->value || !((int)dmflags->value & DF_NO_FALLING) )
			T_Damage (ent, world, world, dir, ent->s.origin, vec3_origin, damage, 0, 0, MOD_FALLING);
	}
	else
	{
		ent->s.event = EV_FALLSHORT;
		PlayerNoise(ent, ent->s.origin, PNOISE_SELF);	//ponko
		return;
	}
}
예제 #5
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->pers.inventory[ent->client->ammo_index] < 1)
	{
		ent->client->ps.gunframe = 6;
		if (level.time >= ent->pain_debounce_time)
		{
			gi.sound(ent, CHAN_VOICE, gi.soundindex("weapons/noammo.wav"), 1, ATTN_NORM, 0);
			ent->pain_debounce_time = level.time + 1;
		}
		NoAmmoWeaponChange (ent);
		return;
	}

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

	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);

	gi.WriteByte (svc_muzzleflash);
	gi.WriteShort (ent-g_edicts);
	gi.WriteByte (MZ_MACHINEGUN | is_silenced);
	gi.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]--;

	// play quad damage sound
	playQuadSound(ent);
}
예제 #6
0
void Machinegun_Fire (edict_t *ent)
{
	vec3_t		start;
	vec3_t		forward, right;
	vec3_t		angles;
	int			damage;
	int			kick = 0;
	vec3_t		offset;
	int item = getWornItem(ent, GIEX_ITEM_WEAPON);
	iteminfo_t	*info = getWornItemInfo(ent, GIEX_ITEM_WEAPON);
	int	i, spread = getMachinegunSpread(ent, item, info);

//	damage = info->arg1 + info->arg2 * ent->client->pers.skill[1];
	damage = getMachinegunDamage(ent, item, info);

	if (!(ent->client->buttons & BUTTON_ATTACK))
	{
		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)
		{
			gi.sound(ent, CHAN_VOICE, gi.soundindex("weapons/noammo.wav"), 1, ATTN_NORM, 0);
			ent->pain_debounce_time = level.time + 1;
		}
		NoAmmoWeaponChange (ent);
		return;
	}

	damage = applyWeaponBonuses(ent, damage, 1);
//	if (is_quad)
//		kick *= 4;

	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;

	// 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, spread, spread, MOD_MACHINEGUN);

	if ((ent->client->silencer_shots > 0) && (ent->client->pers.skill[58] > 7)) {
		ent->client->silencer_shots -= 1;
	} else {
		gi.WriteByte (svc_muzzleflash);
		gi.WriteShort (ent-g_edicts);
		gi.WriteByte (MZ_MACHINEGUN | is_silenced);
		gi.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;
	}
}
예제 #7
0
파일: bot_fire.c 프로젝트: qbism/tmg
//return weapon
void Combat_Level0(edict_t *ent,int foundedenemy,int enewep
				   ,float aim,float distance,int skill)
{
	float		f;
	gclient_t	*client;
	zgcl_t		*zc;

	edict_t		*target;
	int			mywep,i,j,k;
	vec3_t		v,vv,v1,v2;
	qboolean	mod = false;

	trace_t		rs_trace;

	client = ent->client;
	zc = &client->zc;
	target = zc->first_target;


	//-----------------------------------------------------------------------
	//ステータスを反映
	//-----------------------------------------------------------------------
	//チキンは狙いがキツイ==============
	if(zc->battlemode == FIRE_CHIKEN) aim *= 0.7;
	//左右に回避========================
	if(zc->battlemode & FIRE_SHIFT)
	{
		mywep = Get_KindWeapon(client->pers.weapon);
		Get_AimAngle(ent,aim,distance,mywep);

		if(--zc->battlesubcnt > 0)
		{
			if(ent->groundentity)
			{
				if(zc->battlemode & FIRE_SHIFT_R)
				{
					zc->moveyaw = ent->s.angles[YAW] + 90;
					if(zc->moveyaw > 180) zc->moveyaw -= 360;
				}
				else
				{
					zc->moveyaw = ent->s.angles[YAW] - 90;
					if(zc->moveyaw < -180) zc->moveyaw += 360;
				}
				trace_priority = TRP_MOVEKEEP;	//後退処理
			}
		}
		else
		{
			zc->battlemode &= ~FIRE_SHIFT;
		}
	}

	//dodge=============================
	if(Bot[ent->client->zc.botindex].param[BOP_DODGE]
		&& ent->groundentity && !ent->waterlevel)
	{
		AngleVectors (target->client->v_angle, v,NULL, NULL);
		VectorScale (v, 300, v);

		VectorSet(vv, 0, 0,  target->viewheight-8);
		VectorAdd(target->s.origin,vv,vv);
		VectorAdd(vv,v,v);

		VectorSet(v1, -4, -4,-4);
		VectorSet(v2, 4, 4, 4);
		rs_trace = gi.trace(vv,v1,v2,v,target,MASK_SHOT);

		if(rs_trace.ent == ent)
		{
			if(rs_trace.endpos[2] > (ent->s.origin[2] + 4) && random() < 0.4)
			{
				client->ps.pmove.pm_flags |= PMF_DUCKED;
				zc->battleduckcnt = 2 + 8 * random();
			}
			else if(rs_trace.endpos[2] < (ent->s.origin[2] + JumpMax - 24))
			{
				if(zc->route_trace)
				{
					if(Bot_Fall(ent,ent->s.origin,0)) trace_priority = TRP_MOVEKEEP;;
				}
				else
				{
					ent->moveinfo.speed = 0.5;
	
					ent->velocity[2] += VEL_BOT_JUMP;
					gi.sound(ent, CHAN_VOICE, gi.soundindex("*jump1.wav"), 1, ATTN_NORM, 0);
					PlayerNoise(ent, ent->s.origin, PNOISE_SELF);	//pon
					Set_BotAnim(ent,ANIM_JUMP,FRAME_jump1-1,FRAME_jump6);
				}					
			}
		}
	}
	//無視して走る========================
	if(zc->battlemode & FIRE_IGNORE)
	{
		if(--zc->battlecount > 0)
		{
			if(zc->first_target != zc->last_target)
			{
				zc->battlemode = 0;
			}
			else return;
		}
		zc->battlemode = 0;
	}

	//立ち止まって撃つ準備========================
	if(zc->battlemode & FIRE_PRESTAYFIRE)
	{
		if(--zc->battlecount > 0)
		{
			mywep = Get_KindWeapon(client->pers.weapon);
			Get_AimAngle(ent,aim,distance,mywep);
			if(target->client->weaponstate == WEAPON_FIRING && ent->groundentity) ent->client->ps.pmove.pm_flags |= PMF_DUCKED;
			trace_priority = TRP_ALLKEEP;	//動かない
			return;
		}
		if(!(zc->battlemode & FIRE_SHIFT)) zc->battlemode = FIRE_STAYFIRE;			//モード遷移
		zc->battlecount = 5 + (int)(20 * random());
	}

	//立ち止まって撃つ========================
	if(zc->battlemode & FIRE_STAYFIRE)
	{
		if(--zc->battlecount > 0)
		{
			mywep = Get_KindWeapon(client->pers.weapon);
			if(1/*mywep == WEAP_BFG*/) CanUsewep(ent,WEAP_BFG);
			aim *= 0.95;
			Get_AimAngle(ent,aim,distance,mywep);
			if(target->client->weaponstate == WEAPON_FIRING && ent->groundentity)
			{
				if(mywep == WEAP_BFG)
				{
					if(target->s.origin[2] > ent->s.origin[2]) client->ps.pmove.pm_flags |= PMF_DUCKED;
				}
				else client->ps.pmove.pm_flags |= PMF_DUCKED;
			}
			if(!(zc->battlemode & FIRE_SHIFT)) trace_priority = TRP_ALLKEEP;	//動かない
			if(Bot_traceS(ent,target) 
				|| mywep == WEAP_BFG 
				|| mywep == WEAP_GRENADELAUNCHER) client->buttons |= BUTTON_ATTACK;
			return;
		}
		zc->battlemode = 0;
	}

	//FIRE_RUSH	つっこむ========================
	if(zc->battlemode & FIRE_RUSH)
	{
		if(--zc->battlecount > 0)
		{
			mywep = Get_KindWeapon(client->pers.weapon);
			if(1/*mywep == WEAP_BFG*/) CanUsewep(ent,WEAP_BFG);
			aim *= 0.95;
			Get_AimAngle(ent,aim,distance,mywep);
			if(target->client->weaponstate == WEAPON_FIRING && ent->groundentity)
			{
				if(mywep == WEAP_BFG)
				{
					if(target->s.origin[2] > ent->s.origin[2]) client->ps.pmove.pm_flags |= PMF_DUCKED;
				}
				else client->ps.pmove.pm_flags |= PMF_DUCKED;
			}
			trace_priority = TRP_MOVEKEEP;	//後退処理
			zc->moveyaw = ent->s.angles[YAW];

			if(Bot_traceS(ent,target)) client->buttons |= BUTTON_ATTACK;
			return;
		}
		zc->battlemode = 0;
	}

	//後退ファイア(爆発回避)========================
	if(zc->battlemode & FIRE_EXPAVOID)
	{
		if(--zc->battlecount > 0)
		{
			mywep = Get_KindWeapon(client->pers.weapon);
			if(1/*mywep == WEAP_BFG*/) CanUsewep(ent,WEAP_BFG);
			aim *= 0.95;
			Get_AimAngle(ent,aim,distance,mywep);
			if(target->client->weaponstate == WEAPON_FIRING && ent->groundentity)
			{
				if(mywep == WEAP_BFG)
				{
					if(target->s.origin[2] > ent->s.origin[2]) client->ps.pmove.pm_flags |= PMF_DUCKED;
				}
				else client->ps.pmove.pm_flags |= PMF_DUCKED;
			}
			trace_priority = TRP_MOVEKEEP;	//後退処理
			zc->moveyaw = ent->s.angles[YAW] + 180;
			if(zc->moveyaw > 180) zc->moveyaw -= 360;

			if(Bot_traceS(ent,target) 
				|| mywep == WEAP_BFG 
				|| mywep == WEAP_GRENADELAUNCHER) client->buttons |= BUTTON_ATTACK;
			return;
		}
		zc->battlemode = 0;
	}
	//BFGファイア(爆発回避)========================
	if(zc->battlemode & FIRE_BFG)
	{
		if(--zc->battlecount > 0)
		{
			mywep = Get_KindWeapon(client->pers.weapon);
			if(1/*mywep == WEAP_BFG*/) CanUsewep(ent,WEAP_BFG);
			aim *= 0.95;
			Get_AimAngle(ent,aim,distance,mywep);
			if(target->client->weaponstate == WEAPON_FIRING && ent->groundentity)
			{
				if(1/*mywep == WEAP_BFG*/)
				{
					if(target->s.origin[2] > ent->s.origin[2]) client->ps.pmove.pm_flags |= PMF_DUCKED;
				}
				else client->ps.pmove.pm_flags |= PMF_DUCKED;
			}
			trace_priority = TRP_ANGLEKEEP;	//後退処理

			if(Bot_traceS(ent,target) 
				|| mywep == WEAP_BFG 
				|| mywep == WEAP_GRENADELAUNCHER) client->buttons |= BUTTON_ATTACK;
			return;
		}
		zc->battlemode = 0;
	}

	//撃って避難========================
	if(zc->battlemode & FIRE_REFUGE)
	{
		if(--zc->battlecount > 0)
		{
			mywep = Get_KindWeapon(client->pers.weapon);
			//CanUsewep(ent,WEAP_BFG);
			aim *= 0.95;
			Get_AimAngle(ent,aim,distance,mywep);
			if(target->client->weaponstate == WEAPON_FIRING && ent->groundentity)
			{
				if(mywep == WEAP_BFG)
				{
					if(target->s.origin[2] > ent->s.origin[2]) client->ps.pmove.pm_flags |= PMF_DUCKED;
				}
				else client->ps.pmove.pm_flags |= PMF_DUCKED;
			}
			trace_priority = TRP_ANGLEKEEP;	//動かない
//			trace_priority = TRP_ALLKEEP;	//動かない
			if(Bot_traceS(ent,target) 
				|| mywep == WEAP_BFG 
				|| mywep == WEAP_GRENADELAUNCHER) client->buttons |= BUTTON_ATTACK;
			return;
		}
		zc->battlemode = 0;
		zc->routeindex -= 2;
	}

	if(!(client->zc.zccmbstt & CTS_ENEM_NSEE) 
		&& (zc->zcstate & STS_WAITSMASK2)
		&& (target->s.origin[2] - ent->s.origin[2]) < -300)
	{
		if(k = CanUsewep(ent,WEAP_GRENADELAUNCHER))
		{
			mywep = Get_KindWeapon(client->pers.weapon);
			Get_AimAngle(ent,aim,distance,mywep);
			if((target->client->weaponstate == WEAPON_FIRING && ent->groundentity) || (zc->zcstate & STS_WAITSMASK2)) ent->client->ps.pmove.pm_flags |= PMF_DUCKED;
			client->buttons |= BUTTON_ATTACK;
			trace_priority = TRP_ANGLEKEEP;
			return;
		}
		if(k = CanUsewep(ent,WEAP_GRENADES))
		{
			mywep = Get_KindWeapon(client->pers.weapon);
			Get_AimAngle(ent,aim,distance,mywep);
			if(target->client->weaponstate == WEAPON_FIRING && ent->groundentity) ent->client->ps.pmove.pm_flags |= PMF_DUCKED;
			if(ent->client->weaponstate == WEAPON_READY ) client->buttons |= BUTTON_ATTACK;
			trace_priority = TRP_ANGLEKEEP;
			return;
		}
	}

	//-----------------------------------------------------------------------
	//特殊ファイアリング
	//-----------------------------------------------------------------------
	mywep = Get_KindWeapon(client->pers.weapon);

	//左右回避セット========================
	if(!(zc->battlemode & FIRE_SHIFT) && skill > (random() * skill) /*&& distance < 250*/
		&& (30 * random()) < Bot[zc->botindex].param[BOP_OFFENCE])
	{
		k = false;
		if(zc->route_trace && enewep != WEAP_RAILGUN)
		{
			for(i = zc->routeindex;i < (zc->routeindex + 10);i++)
			{
				if(i >= CurrentIndex) break;
				if(Route[i].state == GRS_ITEMS)
				{
					if(Route[i].ent->solid == SOLID_TRIGGER)
					{
						k = true;
						break;
					}
				}				
			}
		}
		if(!k)
		{
			Get_AimAngle(ent,aim,distance,mywep);
			f =target->s.angles[YAW] - ent->s.angles[YAW];

			if(f > 180)
			{
				f = -(360 - f);
			}
			if( f < -180)
			{
				f = -(f + 360);
			}
	
			//俺をみている!!
			if(f <= -160)
			{

				zc->battlemode |= FIRE_SHIFT_L;
				zc->battlesubcnt = 5 + (int)(16 * random());
			}
			else if(f >= 160)
			{
				zc->battlemode |= FIRE_SHIFT_R;
				zc->battlesubcnt = 5 + (int)(16 * random());
			}
		}
	}

	//敵がペンタをとっている========================
	if((FFlg[skill] & FIRE_AVOIDINV)
		&& target->client->invincible_framenum > level.framenum)
	{
//		mywep = Get_KindWeapon(client->pers.weapon);
		Get_AimAngle(ent,aim,distance,mywep);
		trace_priority = TRP_MOVEKEEP;	//後退処理
		zc->moveyaw = ent->s.angles[YAW] + 180;
		if(zc->moveyaw > 180) zc->moveyaw -= 360;
		return;
	}
	//Quad時の処理=================================
	if((FFlg[skill] & FIRE_QUADUSE) 
		&& (ent->client->quad_framenum > level.framenum)
		&& distance < 300)
	{
		j = false;
		if(enewep < WEAP_MACHINEGUN || enewep == WEAP_GRENADES) j = true;

		//Hyper Blaster
		if(k = CanUsewep(ent,WEAP_HYPERBLASTER))
		{
			mywep = Get_KindWeapon(client->pers.weapon);
			Get_AimAngle(ent,aim,distance,mywep);
			client->buttons |= BUTTON_ATTACK;
			trace_priority = TRP_ANGLEKEEP;
			if(j)
			{
				zc->battlemode |= FIRE_RUSH;
				zc->battlecount = 8 + (int)(10 * random());
			}
			return;
		}
		//Chain Gun
		if(k = CanUsewep(ent,WEAP_CHAINGUN))
		{
			mywep = Get_KindWeapon(client->pers.weapon);
			Get_AimAngle(ent,aim,distance,mywep);
			client->buttons |= BUTTON_ATTACK;
			trace_priority = TRP_ANGLEKEEP;
			if(j)
			{
				zc->battlemode |= FIRE_RUSH;
				zc->battlecount = 8 + (int)(10 * random());
			}
			return;
		}
		//Machine Gun
		if(k = CanUsewep(ent,WEAP_MACHINEGUN))
		{
			mywep = Get_KindWeapon(client->pers.weapon);
			Get_AimAngle(ent,aim,distance,mywep);
			client->buttons |= BUTTON_ATTACK;
			trace_priority = TRP_ANGLEKEEP;
			if(j)
			{
				zc->battlemode |= FIRE_RUSH;
				zc->battlecount = 8 + (int)(10 * random());
			}
			return;
		}
		//S-Shotgun
		if(k = CanUsewep(ent,WEAP_SUPERSHOTGUN))
		{
			mywep = Get_KindWeapon(client->pers.weapon);
			Get_AimAngle(ent,aim,distance,mywep);
			client->buttons |= BUTTON_ATTACK;
			trace_priority = TRP_ANGLEKEEP;
			if(j)
			{
				zc->battlemode |= FIRE_RUSH;
				zc->battlecount = 8 + (int)(10 * random());
			}
			return;
		}
	}
	//撃って逃げる処理=================================
	if((FFlg[skill] & FIRE_REFUGE)
		&& zc->battlemode == 0 && zc->route_trace && zc->routeindex > 1 )
	{
		j = false;
		if(enewep >= WEAP_CHAINGUN && enewep != WEAP_GRENADES) j = true;


		Get_RouteOrigin(zc->routeindex - 2,v);

		if(fabs(v[2] - ent->s.origin[2]) < JumpMax && j)
		{
			mywep = Get_KindWeapon(client->pers.weapon);
			if(mywep == WEAP_GRENADELAUNCHER
			|| mywep == WEAP_ROCKETLAUNCHER
	)
			{
				zc->battlemode |= FIRE_REFUGE;			//モード遷移
				zc->battlecount = 8 + (int)(10 * random());
				trace_priority = TRP_ALLKEEP;
				return;
			}
		}
	}
	//トレース中以外のときにグルグルを防ぐ=================================
	if(!zc->route_trace && distance < 100)
	{
		zc->battlemode |= FIRE_EXPAVOID;			//モード遷移
		zc->battlecount = 4 + (int)(8 * random());
		trace_priority = TRP_ALLKEEP;		
	}


	
	//-----------------------------------------------------------------------
	//プライオリティ
	//-----------------------------------------------------------------------	
	//BFG
	if(distance > 200)
	{
		if(B_UseBfg(ent,target,enewep,aim,distance,skill)) goto FIRED;
	}
	
	for(i = 0;i < 3;i++)
	{
		mywep = Get_KindWeapon(client->pers.weapon);
		
		if(i == 0 && zc->secwep_selected) continue;

		//try to select secondary weapon
		if(i == 0 && zc->secwep_selected) i = 1;
		else if(i == 0 && foundedenemy < 3 
			&& target->health < 50 && !zc->secwep_selected
			&& ent->health >= 50)
		{
			if((9 * random()) < Bot[zc->botindex].param[BOP_COMBATSKILL])
			{
				zc->secwep_selected = 2;
				i = 1;
			}
		}

		if(i == 2)
		{
			if(zc->secwep_selected)
			{
				zc->secwep_selected = 0;
				j = 0;
			}
			else break;
		}
		else j = i;

		if(distance > 100 && (mywep == WEAP_BFG || random() < 0.5))
		{
			if(B_UseBfg(ent,target,enewep,aim,distance,skill)) goto FIRED;
		}

		switch(Bot[zc->botindex].param[BOP_PRIWEP + j])
		{
			case WEAP_RAILGUN:

			if(distance > 1 || voosh->value > 0 )
			{
				if(B_UseRailgun(ent,target,enewep,aim,distance,skill)|| voosh->value) 
					goto FIRED;
			}
			break;


			case WEAP_BFG:
				if(distance > 100)
				{
					if(B_UseBfg(ent,target,enewep,aim,distance,skill)) goto FIRED;
				}
				break;
			case WEAP_HYPERBLASTER:
				if(distance < 1200)
				{
					if(B_UseHyperBlaster(ent,target,enewep,aim,distance,skill)) goto FIRED;			
				}
				break;
		
			case WEAP_ROCKETLAUNCHER:
				if(distance > 100 && distance < 1200/*|| mywep == WEAP_ROCKETLAUNCHER*/)
				{
					if(B_UseRocket(ent,target,enewep,aim,distance,skill)) goto FIRED;			
				}
				break;
		
			case WEAP_GRENADELAUNCHER:
				if(distance > 100 && distance < 400 && (target->s.origin[2] - ent->s.origin[2]) < 200)
				{
					if(B_UseGrenadeLauncher(ent,target,enewep,aim,distance,skill)) goto FIRED;
				}
				break;
			case WEAP_CHAINGUN:
			case WEAP_MACHINEGUN:
				if(distance < 1200)
				{
					if(B_UseChainGun(ent,target,enewep,aim,distance,skill)) goto FIRED;
				}
				if(distance < 1200)
				{
					if(B_UseMachineGun(ent,target,enewep,aim,distance,skill)) goto FIRED;
				}
				break;
			case WEAP_SUPERSHOTGUN:
			case WEAP_SHOTGUN:
				if(distance < 1200)
				{
					if(B_UseSuperShotgun(ent,target,enewep,aim,distance,skill)) goto FIRED;
				}
				if(distance < 1200)
				{
					if(B_UseShotgun(ent,target,enewep,aim,distance,skill)) goto FIRED;
				}
			case WEAP_GRENADES:
				if(distance < 1200)
				{
					if(B_UseHandGrenade(ent,target,enewep,aim,distance,skill)) goto FIRED;
				}
				break;
			default:
				break;
		}
	}

	
	//-----------------------------------------------------------------------
	//通常ファイアリング
	//-----------------------------------------------------------------------
	zc->secwep_selected = 0;
	//BFG
	if(distance > 200)
	{
		if(B_UseBfg(ent,target,enewep,aim,distance,skill)) goto FIRED;
	}

	//Hyper Blaster
	if(distance < 1200)
	{
		if(B_UseHyperBlaster(ent,target,enewep,aim,distance,skill)) goto FIRED;
	}



	//Rocket
	if((distance > 100 && distance < 1200)/*|| mywep == WEAP_ROCKETLAUNCHER*/)
	{
		if(B_UseRocket(ent,target,enewep,aim,distance,skill)) goto FIRED;
	}
	

	//Railgun
	if(distance > 1200 || voosh->value)
	{
		if(B_UseRailgun(ent,target,enewep,aim,distance,skill)||voosh->value) goto FIRED;
	}
	
	//Grenade Launcher
	if(distance > 100 && distance < 400 && (target->s.origin[2] - ent->s.origin[2]) < 200)
	{
		if(B_UseGrenadeLauncher(ent,target,enewep,aim,distance,skill)) goto FIRED;
	}
	//Chain Gun
	if(distance < 1200)
	{
		if(B_UseChainGun(ent,target,enewep,aim,distance,skill)) goto FIRED;
	}
	//Machine Gun
	if(distance < 1200)
	{
		if(B_UseMachineGun(ent,target,enewep,aim,distance,skill)) goto FIRED;
	}
	//S-Shotgun
	if(distance < 1200)
	{
		if(B_UseSuperShotgun(ent,target,enewep,aim,distance,skill)) goto FIRED;
	}
	
	if((FFlg[skill] & FIRE_IGNORE)
		&& distance > 400 && ent->groundentity
		&& !(zc->zcstate & STS_WAITSMASK))
	{
		zc->battlemode = FIRE_IGNORE;
		zc->battlecount = 5 + (int)(10 * random());

	} 

	//Shotgun
	if(distance < 1200)
	{
		if(B_UseShotgun(ent,target,enewep,aim,distance,skill)) goto FIRED;
	}
	//Hand Grenade
	if(distance < 400)
	{
		if(B_UseHandGrenade(ent,target,enewep,aim,distance,skill)) goto FIRED;
	}

	//Blaster
	if(distance < 1200)
	{
		if(B_UseBlaster(ent,target,enewep,aim,distance,skill)) goto FIRED;
	}

	VectorSubtract(zc->vtemp,ent->s.origin,v);
	ent->s.angles[YAW] = Get_yaw(v);
	ent->s.angles[PITCH] = Get_pitch(v);
	trace_priority = TRP_ANGLEKEEP;
	return;

FIRED:
	if(zc->secwep_selected == 2) zc->secwep_selected = 1;
	
	//チキンやろう========================
	if(zc->battlemode == FIRE_CHIKEN)
	{
		if(--zc->battlesubcnt > 0  && ent->groundentity && ent->waterlevel < 2)
		{
			f =target->s.angles[YAW] - ent->s.angles[YAW];

			if(f > 180)
			{
				f = -(360 - f);
			}
			if( f < -180)
			{
				f = -(f + 360);
			}
			if(fabs(f) >= 150) 
			{
				zc->battlemode = 0;
			}
			else 
			{
				if(client->weaponstate != WEAPON_READY
					&& target->s.origin[2] < ent->s.origin[2] )
				{
					if(mywep == WEAP_ROCKETLAUNCHER 
						|| mywep == WEAP_GRENADELAUNCHER
						|| mywep == WEAP_RAILGUN)
						client->ps.pmove.pm_flags |= PMF_DUCKED;
					else if(Bot[zc->botindex].param[BOP_COMBATSKILL] >= 7)
					{
						if(mywep == WEAP_SHOTGUN 
							|| mywep == WEAP_SUPERSHOTGUN
							|| mywep == WEAP_BLASTER)
							client->ps.pmove.pm_flags |= PMF_DUCKED;
					}
				}
				trace_priority = TRP_ALLKEEP;
			}
			return;
		}
		else zc->battlemode = 0;
	}
	else if(zc->battlemode == 0 && distance > 200 
		&& ent->groundentity && ent->waterlevel < 2
		&& (9 * random()) > Bot[zc->botindex].param[BOP_OFFENCE])
	{
		mywep = Get_KindWeapon(client->pers.weapon);
		if(mywep > WEAP_BLASTER && target->client->zc.first_target != ent)
		{
			f =target->s.angles[YAW] - ent->s.angles[YAW];

			if(f > 180)
			{
				f = -(360 - f);
			}
			if( f < -180)
			{
				f = -(f + 360);
			}
			if(fabs(f) < 150)
			{
				zc->battlemode = FIRE_CHIKEN;
				zc->battlesubcnt = 5 + (int)(random() * 8);
				trace_priority = TRP_ALLKEEP;
			}
		}
	}
}
예제 #8
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 (deathmatch->value)
		damage = 6;
	else
		damage = 8;

	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->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;
		gi.sound(ent, CHAN_AUTO, gi.soundindex("weapons/chngnd1a.wav"), 1, ATTN_IDLE, 0);
	}
	else
	{
		ent->client->weapon_sound = gi.soundindex("weapons/chngnl1a.wav");
	}

	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)
		{
			gi.sound(ent, CHAN_VOICE, gi.soundindex("weapons/noammo.wav"), 1, ATTN_NORM, 0);
			ent->pain_debounce_time = level.time + 1;
		}
		NoAmmoWeaponChange (ent);
		return;
	}

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

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

  if(EMPNukeCheck(ent, ent->s.origin))
  {
		gi.sound (ent, CHAN_AUTO, gi.soundindex("items/empnuke/emp_missfire.wav"), 1, ATTN_NORM, 0);
		return;
	}

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

	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
	gi.WriteByte (svc_muzzleflash);
	gi.WriteShort (ent-g_edicts);
	gi.WriteByte ((MZ_CHAINGUN1 + shots - 1) | is_silenced);
	gi.multicast (ent->s.origin, MULTICAST_PVS);

	PlayerNoise(ent, start, PNOISE_WEAPON);

	// play quad damage sound
	playQuadSound(ent);
}
예제 #9
0
파일: g_weapon.c 프로젝트: pmm33/pmm33
/*
=================
fire_bow
=================
*/
void arrow_touch(edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
{
	qboolean damageSuccess = false;
	int r;

	if (other == self->owner)
		return;

	if (surf && (surf->flags & SURF_SKY))
	{
		G_FreeEdict (self);
		return;
	}

	if (self->owner->client)
		PlayerNoise(self->owner, self->s.origin, PNOISE_IMPACT);

	if (other->takedamage)
	{
		r = rand() % 100;
		if (r < self->owner->client->pers.marksman * 2)											// Calculate damageSuccess based on marksman skill
			{
				damageSuccess = true;															// The hit will successfully do damage
				if (self->owner->client->pers.marksman < 100)									// If the marksman skill is less than the skill cap
				{
					self->owner->client->pers.marksman = self->owner->client->pers.marksman + 0.01;					// Add progress to the skill
					if ((self->owner->client->pers.marksman - (int)self->owner->client->pers.marksman) * 100 >= (int)self->owner->client->pers.marksman - 25)		// If the skill levels
					{
						self->owner->client->pers.marksman = self->owner->client->pers.marksman + (1 - (self->owner->client->pers.marksman - (int)self->owner->client->pers.marksman));	// Increase the skill to the next level
						gi.centerprintf(self->owner, "Your Marksman Skill Has Increased To %i\n", (int)self->owner->client->pers.marksman);			// Print that the player's skill has increased
						gi.sound(self->owner, CHAN_AUTO, gi.soundindex("morrowind/skill.wav"), 1, ATTN_NORM, 0);				// Play skill up sound
					}
				}
			}

		if (damageSuccess == true)
		{
			T_Damage(other, self, self->owner, self->velocity, self->s.origin, plane->normal, self->dmg, 1, DAMAGE_ENERGY, MOD_BOW);
			gi.sound(other, CHAN_AUTO, gi.soundindex("morrowind/BodyHit.wav"), 1, ATTN_NORM, 0);
			/*
			gi.WriteByte (svc_temp_entity);
			gi.WriteByte (TE_BLOOD);
			gi.WritePosition (self->s.origin);
			gi.multicast (self->s.origin, MULTICAST_PVS);
			*/
		}
		else
			gi.sound(other, CHAN_AUTO, gi.soundindex("morrowind/Miss.wav"), 1, ATTN_NORM, 0);
	}
	else
	{
		gi.WriteByte (svc_temp_entity);
		gi.WriteByte (TE_SPARKS);
		gi.WritePosition (self->s.origin);
		if (!plane)
			gi.WriteDir (vec3_origin);
		else
			gi.WriteDir (plane->normal);
		gi.multicast (self->s.origin, MULTICAST_PVS);
	}

	G_FreeEdict (self);
}
예제 #10
0
파일: bot_fire.c 프로젝트: qbism/tmg
//------------------------------------------------------------
qboolean B_UseRocket(edict_t *ent,edict_t *target,int enewep,float aim,float distance,int skill)
{
	int k,mywep;
	zgcl_t		*zc;
	gclient_t	*client;

	client = ent->client;
	zc = &client->zc;

	if(k = CanUsewep(ent,WEAP_ROCKETLAUNCHER))
	{
		mywep = Get_KindWeapon(client->pers.weapon);
		Get_AimAngle(ent,aim,distance,mywep);
		if(trace_priority < TRP_ANGLEKEEP) trace_priority = TRP_ANGLEKEEP;
		if((FFlg[skill] & FIRE_PRESTAYFIRE)
			&& ((distance > 500 && random() < 0.1) || fabs(ent->s.angles[PITCH]) > 45 ) 
			&& Bot_traceS(ent,target)
			&& (enewep <= WEAP_MACHINEGUN || enewep == WEAP_GRENADES))
		{
			if(ent->groundentity || zc->waterstate)
			{
				zc->battlemode |= FIRE_PRESTAYFIRE;
				zc->battlecount = 2 + (int)(6 * random());
				trace_priority = TRP_ALLKEEP;
				return true;
			}
		}
		if((FFlg[skill] & FIRE_JUMPROC) && random() < 0.3 
			&& (target->s.origin[2] - ent->s.origin[2]) < JumpMax
			&& !(client->ps.pmove.pm_flags && PMF_DUCKED)) 
		{
			if(ent->groundentity && !ent->waterlevel <= 1)
			{
				if(zc->route_trace)
				{
					if(Bot_Fall(ent,ent->s.origin,0))
					{
						trace_priority = TRP_ALLKEEP;
						if(Bot_traceS(ent,target)) client->buttons |= BUTTON_ATTACK;
						return true;
					}
				}
				else
				{
					ent->moveinfo.speed = 0;

					ent->velocity[2] += VEL_BOT_JUMP;
					gi.sound(ent, CHAN_VOICE, gi.soundindex("*jump1.wav"), 1, ATTN_NORM, 0);
					PlayerNoise(ent, ent->s.origin, PNOISE_SELF);	//pon
					Set_BotAnim(ent,ANIM_JUMP,FRAME_jump1-1,FRAME_jump6);
					trace_priority = TRP_ALLKEEP;
					if(Bot_traceS(ent,target)) client->buttons |= BUTTON_ATTACK;
					return true;
				}
			}
		}
		else if((FFlg[skill] & FIRE_EXPAVOID)
		&& distance < 300 && random() < 0.5 
		&& Bot_traceS(ent,target))
		{
			if(ent->groundentity || zc->waterstate)
			{
				zc->battlemode |= FIRE_EXPAVOID;
				zc->battlecount = 4 + (int)(6 * random());
				trace_priority = TRP_ALLKEEP;
				return true;
			}
		}
		if(Bot_traceS(ent,target)) client->buttons |= BUTTON_ATTACK;
		return true;
	}
	return false;
}
예제 #11
0
파일: p_weapon.c 프로젝트: qbism/tmg
void weapon_railgun_fire (edict_t *ent)
{
	vec3_t		start;
	vec3_t		forward, right;
	vec3_t		offset;
	int			damage;
	int			kick;
//RAV
if(ent->client->pers.pl_state ==5 )
	return;

if( ent->client->pers.pl_state < 1 || ent->client->resp.spectator
   ||(ctf->value && ent->client->resp.ctf_team < 1))
{
	ent->movetype = MOVETYPE_NOCLIP;
	ent->solid = SOLID_NOT;
	ent->svflags |= SVF_NOCLIENT;
	ent->client->resp.ctf_team = CTF_NOTEAM;
	ent->client->ps.gunindex = 0;
	ent->client->pers.pl_state = 0;
	gi.linkentity (ent);
	ent->client->resp.spectator = true;
	return;
}

//
	if (deathmatch->value)
	{	// normal damage is too extreme in dm
		damage = rg_damage->value;
		kick = rg_kick->value;
	}
	else
	{
		damage = 150;
		kick = 250;
	}

	if (is_quad)
	{
		damage *= 4;
		kick *= 4;
	}//DB
  if (is_strength)
	{
		damage *= 2;
		kick *= 2;
	}
//DB
	//RAV
	if(voosh->value)
	{
		damage = (int)raildamage->value;
		kick = (int)railkick->value;
	}
	//
	AngleVectors (ent->client->v_angle, forward, right, NULL);

	VectorScale (forward, -3, ent->client->kick_origin);
	ent->client->kick_angles[0] = -3;

	VectorSet(offset, 0, 7,  ent->viewheight-8);
	P_ProjectSource (ent->client, ent->s.origin, offset, forward, right, start);
	fire_rail (ent, start, forward, damage, kick);

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

	ent->client->ps.gunframe++;
	PlayerNoise(ent, start, PNOISE_WEAPON);

//RAV
	//allow for camper checking
	ent->client->check_camping = true;
//
	if (! ( dmflag & DF_INFINITE_AMMO ) )
		if(voosh->value == 0)//RAV
			ent->client->pers.inventory[ent->client->ammo_index]--;
}
예제 #12
0
파일: g_weapon.c 프로젝트: ZFect/yquake2
void
bfg_touch(edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
{
	if (!self || !other)
	{
		G_FreeEdict(self);
		return;
	}

	if (other == self->owner)
	{
		return;
	}

	if (surf && (surf->flags & SURF_SKY))
	{
		G_FreeEdict(self);
		return;
	}

	if (self->owner && self->owner->client)
	{
		PlayerNoise(self->owner, self->s.origin, PNOISE_IMPACT);
	}

	/* core explosion - prevents firing it into the wall/floor */
	if (other->takedamage)
	{
		if (plane)
		{
			T_Damage(other, self, self->owner, self->velocity, self->s.origin,
					plane->normal, 200, 0, 0, MOD_BFG_BLAST);
		}
		else
		{
			T_Damage(other, self, self->owner, self->velocity, self->s.origin,
					vec3_origin, 200, 0, 0, MOD_BFG_BLAST);
		}
	}

	T_RadiusDamage(self, self->owner, 200, other, 100, MOD_BFG_BLAST);

	gi.sound(self, CHAN_VOICE, gi.soundindex(
					"weapons/bfg__x1b.wav"), 1, ATTN_NORM, 0);
	self->solid = SOLID_NOT;
	self->touch = NULL;
	VectorMA(self->s.origin, -1 * FRAMETIME, self->velocity, self->s.origin);
	VectorClear(self->velocity);
	self->s.modelindex = gi.modelindex("sprites/s_bfg3.sp2");
	self->s.frame = 0;
	self->s.sound = 0;
	self->s.effects &= ~EF_ANIM_ALLFAST;
	self->think = bfg_explode;
	self->nextthink = level.time + FRAMETIME;
	self->enemy = other;

	gi.WriteByte(svc_temp_entity);
	gi.WriteByte(TE_BFG_BIGEXPLOSION);
	gi.WritePosition(self->s.origin);
	gi.multicast(self->s.origin, MULTICAST_PVS);
}
예제 #13
0
파일: g_weapon.c 프로젝트: basecq/q2dos
/*
=================
fire_blaster

Fires a single blaster bolt.  Used by the blaster and hyper blaster.
=================
*/
void blaster_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
{
	int		mod;

	if (!self || !other)
	{
		G_FreeEdict(self);
		return;
	}

	if (other == self->owner)
	{
		return;
	}

	if (surf && (surf->flags & SURF_SKY))
	{
		G_FreeEdict(self);
		return;
	}

	if (self->owner->client)
	{
		PlayerNoise(self->owner, self->s.origin, PNOISE_IMPACT);
	}

	if (other->takedamage)
	{
		if (self->spawnflags & 1)
		{
			mod = MOD_HYPERBLASTER;
		}
		else
		{
			mod = MOD_BLASTER;
		}

		T_Damage(other, self, self->owner, self->velocity, self->s.origin,
				plane->normal, self->dmg, 1, DAMAGE_ENERGY, mod);
	}
	else
	{
		gi.WriteByte (svc_temp_entity);
		// RAFAEL
		if (self->s.effects & EF_BLUEHYPERBLASTER)	// Knightmare- this was checking bit TE_BLUEHYPERBLASTER
			gi.WriteByte (TE_BLUEHYPERBLASTER);			// Knightmare- TE_BLUEHYPERBLASTER is broken (parse error) in most Q2 engines
		else
			gi.WriteByte (TE_BLASTER);
		gi.WritePosition(self->s.origin);

		if (!plane)
		{
			gi.WriteDir(vec3_origin);
		}
		else
		{
			gi.WriteDir(plane->normal);
		}

		gi.multicast(self->s.origin, MULTICAST_PVS);
	}

	G_FreeEdict(self);
}
예제 #14
0
파일: p_client.c 프로젝트: ar664/Quak2Mod
/*
==============
ClientThink

This will be called once for each client frame, which will
usually be a couple times for each server frame.
==============
*/
void ClientThink (edict_t *ent, usercmd_t *ucmd)
{
	gclient_t	*client;
	edict_t	*other;
	int		i, j;
	pmove_t	pm;

	level.current_entity = ent;
	client = ent->client;

	if (level.intermissiontime)
	{
		client->ps.pmove.pm_type = PM_FREEZE;
		// can exit intermission after five seconds
		if (level.time > level.intermissiontime + 5.0 
			&& (ucmd->buttons & BUTTON_ANY) )
			level.exitintermission = true;
		return;
	}

	pm_passent = ent;

	if (ent->client->chase_target) {

		client->resp.cmd_angles[0] = SHORT2ANGLE(ucmd->angles[0]);
		client->resp.cmd_angles[1] = SHORT2ANGLE(ucmd->angles[1]);
		client->resp.cmd_angles[2] = SHORT2ANGLE(ucmd->angles[2]);

	} else {

		// set up for pmove
		memset (&pm, 0, sizeof(pm));

		if (ent->movetype == MOVETYPE_NOCLIP)
			client->ps.pmove.pm_type = PM_SPECTATOR;
		else if (ent->s.modelindex != 255)
			client->ps.pmove.pm_type = PM_GIB;
		else if (ent->deadflag)
			client->ps.pmove.pm_type = PM_DEAD;
		else
			client->ps.pmove.pm_type = PM_NORMAL;

		client->ps.pmove.gravity = 0;
		pm.s = client->ps.pmove;

		for (i=0 ; i<3 ; i++)
		{
			pm.s.origin[i] = ent->s.origin[i]*8;
			pm.s.velocity[i] = ent->velocity[i]*8;
		}

		if (memcmp(&client->old_pmove, &pm.s, sizeof(pm.s)))
		{
			pm.snapinitial = true;
	//		gi.dprintf ("pmove changed!\n");
		}

		pm.cmd = *ucmd;

		pm.trace = PM_trace;	// adds default parms
		pm.pointcontents = gi.pointcontents;

		// perform a pmove
		gi.Pmove (&pm);

		// save results of pmove
		client->ps.pmove = pm.s;
		client->old_pmove = pm.s;

		for (i=0 ; i<3 ; i++)
		{
			ent->s.origin[i] = pm.s.origin[i]*0.125;
			ent->velocity[i] = pm.s.velocity[i]*0.125;
		}

		VectorCopy (pm.mins, ent->mins);
		VectorCopy (pm.maxs, ent->maxs);

		client->resp.cmd_angles[0] = SHORT2ANGLE(ucmd->angles[0]);
		client->resp.cmd_angles[1] = SHORT2ANGLE(ucmd->angles[1]);
		client->resp.cmd_angles[2] = SHORT2ANGLE(ucmd->angles[2]);

		if (ent->groundentity && !pm.groundentity && (pm.cmd.upmove >= 10) && (pm.waterlevel == 0))
		{
			gi.sound(ent, CHAN_VOICE, gi.soundindex("*jump1.wav"), 1, ATTN_NORM, 0);
			PlayerNoise(ent, ent->s.origin, PNOISE_SELF);
		}

		ent->viewheight = pm.viewheight;
		ent->waterlevel = pm.waterlevel;
		ent->watertype = pm.watertype;
		ent->groundentity = pm.groundentity;
		if (pm.groundentity)
			ent->groundentity_linkcount = pm.groundentity->linkcount;

		if (ent->deadflag)
		{
			client->ps.viewangles[ROLL] = 40;
			client->ps.viewangles[PITCH] = -15;
			client->ps.viewangles[YAW] = client->killer_yaw;
		}
		else
		{
			VectorCopy (pm.viewangles, client->v_angle);
			VectorCopy (pm.viewangles, client->ps.viewangles);
		}

		gi.linkentity (ent);

		if (ent->movetype != MOVETYPE_NOCLIP)
			G_TouchTriggers (ent);

		// touch other objects
		for (i=0 ; i<pm.numtouch ; i++)
		{
			other = pm.touchents[i];
			for (j=0 ; j<i ; j++)
				if (pm.touchents[j] == other)
					break;
			if (j != i)
				continue;	// duplicated
			if (!other->touch)
				continue;
			other->touch (other, ent, NULL, NULL);
		}

	}

	client->oldbuttons = client->buttons;
	client->buttons = ucmd->buttons;
	client->latched_buttons |= client->buttons & ~client->oldbuttons;

	// save light level the player is standing on for
	// monster sighting AI
	ent->light_level = ucmd->lightlevel;

	// fire weapon from final position if needed
	if (client->latched_buttons & BUTTON_ATTACK)
	{
		if (client->resp.spectator) {

			client->latched_buttons = 0;

			if (client->chase_target) {
				client->chase_target = NULL;
				client->ps.pmove.pm_flags &= ~PMF_NO_PREDICTION;
			} else
				GetChaseTarget(ent);

		} else if (!client->weapon_thunk) {
			client->weapon_thunk = true;
			Think_Weapon (ent);
		}
	}

	if (client->resp.spectator) {
		if (ucmd->upmove >= 10) {
			if (!(client->ps.pmove.pm_flags & PMF_JUMP_HELD)) {
				client->ps.pmove.pm_flags |= PMF_JUMP_HELD;
				if (client->chase_target)
					ChaseNext(ent);
				else
					GetChaseTarget(ent);
			}
		} else
			client->ps.pmove.pm_flags &= ~PMF_JUMP_HELD;
	}

	// update chase cam if being followed
	for (i = 1; i <= maxclients->value; i++) {
		other = g_edicts + i;
		if (other->inuse && other->client->chase_target == ent)
			UpdateChaseCam(other);
	}
}
예제 #15
0
파일: weapon.c 프로젝트: phine4s/xatrix
void
weapon_bfg_fire(edict_t *ent)
{
	vec3_t offset, start;
	vec3_t forward, right;
	int damage;
	float damage_radius = 1000;

  	if (!ent)
	{
		return;
	}

	if (deathmatch->value)
	{
		damage = 200;
	}
	else
	{
		damage = 500;
	}

	if (ent->client->ps.gunframe == 9)
	{
		/* send muzzle flash */
		gi.WriteByte(svc_muzzleflash);
		gi.WriteShort(ent - g_edicts);
		gi.WriteByte(MZ_BFG | is_silenced);
		gi.multicast(ent->s.origin, MULTICAST_PVS);

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

		PlayerNoise(ent, start, PNOISE_WEAPON);
		return;
	}

	/* cells can go down during windup (from power armor hits), so
	   check again and abort firing if we don't have enough now */
	if (ent->client->pers.inventory[ent->client->ammo_index] < 50)
	{
		ent->client->ps.gunframe++;
		return;
	}

	if (is_quad)
	{
		damage *= 4;
	}

	AngleVectors(ent->client->v_angle, forward, right, NULL);

	VectorScale(forward, -2, ent->client->kick_origin);

	/* make a big pitch kick with an inverse fall */
	ent->client->v_dmg_pitch = -40;
	ent->client->v_dmg_roll = crandom() * 8;
	ent->client->v_dmg_time = level.time + DAMAGE_TIME;

	VectorSet(offset, 8, 8, ent->viewheight - 8);
	P_ProjectSource(ent->client, ent->s.origin, offset, forward, right, start);
	fire_bfg(ent, start, forward, damage, 400, damage_radius);

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

	PlayerNoise(ent, start, PNOISE_WEAPON);

	if (!((int)dmflags->value & DF_INFINITE_AMMO))
	{
		ent->client->pers.inventory[ent->client->ammo_index] -= 50;
	}
}
예제 #16
0
/*
=============
P_WorldEffects
=============
*/
void P_WorldEffects (void)
{
	qboolean breather;
	qboolean envirosuit;
	int waterlevel, old_waterlevel;

	if (current_player->movetype == MOVETYPE_NOCLIP)
	{
		current_player->air_finished = level.time + 12;	// don't need air
		return;
	}

	waterlevel = current_player->waterlevel;
	old_waterlevel = current_client->old_waterlevel;
	current_client->old_waterlevel = waterlevel;

	breather = current_client->breather_framenum > level.framenum;
	envirosuit = current_client->enviro_framenum > level.framenum;

	//
	// if just entered a water volume, play a sound
	//
	if (!old_waterlevel && waterlevel)
	{
		PlayerNoise (current_player, current_player->s.origin, PNOISE_SELF);
		if (current_player->watertype & CONTENTS_LAVA)
			gi.sound (current_player, CHAN_BODY,
			gi.soundindex ("player/lava_in.wav"), 1, ATTN_NORM, 0);
		else if (current_player->watertype & CONTENTS_SLIME)
			gi.sound (current_player, CHAN_BODY,
			gi.soundindex ("player/watr_in.wav"), 1, ATTN_NORM, 0);
		else if (current_player->watertype & CONTENTS_WATER)
			gi.sound (current_player, CHAN_BODY,
			gi.soundindex ("player/watr_in.wav"), 1, ATTN_NORM, 0);

		current_player->flags |= FL_INWATER;

		// clear damage_debounce, so the pain sound will play immediately
		current_player->damage_debounce_time = level.time - 1;
	}

	//
	// if just completely exited a water volume, play a sound
	//
	if (old_waterlevel && !waterlevel)
	{
		PlayerNoise (current_player, current_player->s.origin, PNOISE_SELF);
		gi.sound (current_player, CHAN_BODY,
		gi.soundindex ("player/watr_out.wav"), 1, ATTN_NORM, 0);
		current_player->flags &= ~FL_INWATER;
	}

	//
	// check for head just going under water
	//
	if (old_waterlevel != 3 && waterlevel == 3)
	{
		gi.sound (current_player, CHAN_BODY,
		gi.soundindex ("player/watr_un.wav"), 1, ATTN_NORM, 0);
	}

	//
	// check for head just coming out of water
	//
	if (old_waterlevel == 3 && waterlevel != 3)
	{
		if (current_player->air_finished < level.time)
		{			// gasp for air
			gi.sound (current_player, CHAN_VOICE,
			gi.soundindex ("player/gasp1.wav"), 1, ATTN_NORM, 0);
			PlayerNoise (current_player, current_player->s.origin, PNOISE_SELF);
		}
		else if (current_player->air_finished < level.time + 11)
		{			// just break surface
			gi.sound (current_player, CHAN_VOICE,
			gi.soundindex ("player/gasp2.wav"), 1, ATTN_NORM, 0);
		}
	}

	//
	// check for drowning
	//
	if (waterlevel == 3)
	{
		// breather or envirosuit give air
		if (breather || envirosuit)
		{
			current_player->air_finished = level.time + 10;

			if (((int)(current_client->breather_framenum - level.framenum) % 25) == 0)
			{
				if (!current_client->breather_sound)
					gi.sound (current_player, CHAN_AUTO,
					gi.soundindex("player/u_breath1.wav"), 1, ATTN_NORM, 0);
				else
					gi.sound (current_player, CHAN_AUTO,
					gi.soundindex("player/u_breath2.wav"), 1, ATTN_NORM, 0);
				current_client->breather_sound ^= 1;
				PlayerNoise (current_player, current_player->s.origin,
				PNOISE_SELF);
				//FIXME: release a bubble?
			}
		}

		// if out of air, start drowning
		if (current_player->air_finished < level.time)
		{			// drown!
			if (current_player->client->next_drown_time < level.time
			&& current_player->health > 0)
			{
				current_player->client->next_drown_time = level.time + 1;

				// take more damage the longer underwater
				current_player->dmg += 2;
				if (current_player->dmg > 15)
					current_player->dmg = 15;

				// play a gurp sound instead of a normal pain sound
				if (current_player->health <= current_player->dmg)
					gi.sound (current_player, CHAN_VOICE,
					gi.soundindex ("player/drown1.wav"), 1, ATTN_NORM, 0);
				else if (rand () & 1)
					gi.sound (current_player, CHAN_VOICE,
					gi.soundindex ("*gurp1.wav"), 1, ATTN_NORM, 0);
				else
					gi.sound (current_player, CHAN_VOICE,
					gi.soundindex ("*gurp2.wav"), 1, ATTN_NORM, 0);

				current_player->pain_debounce_time = level.time;

				T_Damage (current_player, world, world, vec3_origin,
				current_player->s.origin, vec3_origin,
				current_player->dmg, 0, DAMAGE_NO_ARMOR, MOD_WATER);
			}
		}
	}
	else
	{
		current_player->air_finished = level.time + 12;
		current_player->dmg = 2;
	}

	//
	// check for sizzle damage
	//
	if (waterlevel && (current_player->watertype & (CONTENTS_LAVA | CONTENTS_SLIME)))
	{
		if (current_player->watertype & CONTENTS_LAVA)
		{
			if (current_player->health > 0
			&& current_player->pain_debounce_time <= level.time
			&& current_client->invincible_framenum < level.framenum)
			{
				if (rand () & 1)
					gi.sound (current_player, CHAN_VOICE,
					gi.soundindex ("player/burn1.wav"), 1, ATTN_NORM, 0);
				else
					gi.sound (current_player, CHAN_VOICE,
					gi.soundindex ("player/burn2.wav"), 1, ATTN_NORM, 0);

				current_player->pain_debounce_time = level.time + 1;
			}

			if (envirosuit)	// take 1/3 damage with envirosuit
				T_Damage (current_player, world, world, vec3_origin,
				current_player->s.origin, vec3_origin, 1 * waterlevel, 0, 0, MOD_LAVA);
			else
				T_Damage (current_player, world, world, vec3_origin,
				current_player->s.origin, vec3_origin, 3 * waterlevel, 0, 0, MOD_LAVA);
		}

		if (current_player->watertype & CONTENTS_SLIME && !envirosuit)
		{			// no damage from slime with envirosuit
			T_Damage (current_player, world, world, vec3_origin,
				current_player->s.origin, vec3_origin, 1 * waterlevel, 0, 0, MOD_SLIME);
		}
	}
}
예제 #17
0
파일: weapon.c 프로젝트: phine4s/xatrix
void
weapon_ionripper_fire(edict_t *ent)
{
	vec3_t start;
	vec3_t forward, right;
	vec3_t offset;
	vec3_t tempang;
	int damage;

  	if (!ent)
	{
		return;
	}

	if (deathmatch->value)
	{
		/* tone down for deathmatch */
		damage = 30;
	}
	else
	{
		damage = 50;
	}

	if (is_quad)
	{
		damage *= 4;
	}

	VectorCopy(ent->client->v_angle, tempang);
	tempang[YAW] += crandom();

	AngleVectors(tempang, forward, right, NULL);

	VectorScale(forward, -3, ent->client->kick_origin);
	ent->client->kick_angles[0] = -3;

	VectorSet(offset, 16, 7, ent->viewheight - 8);

	P_ProjectSource(ent->client, ent->s.origin, offset, forward, right, start);

	fire_ionripper(ent, start, forward, damage, 500, EF_IONRIPPER);

	/* send muzzle flash */
	gi.WriteByte(svc_muzzleflash);
	gi.WriteShort(ent - g_edicts);
	gi.WriteByte(MZ_IONRIPPER | is_silenced);
	gi.multicast(ent->s.origin, MULTICAST_PVS);

	ent->client->ps.gunframe++;
	PlayerNoise(ent, start, PNOISE_WEAPON);

	if (!((int)dmflags->value & DF_INFINITE_AMMO))
	{
		ent->client->pers.inventory[ent->client->ammo_index] -=
			ent->client->pers.weapon->quantity;
	}

	if (ent->client->pers.inventory[ent->client->ammo_index] < 0)
	{
		ent->client->pers.inventory[ent->client->ammo_index] = 0;
	}
}
예제 #18
0
void weapon_bfg_fire (edict_t *ent)
{
	vec3_t	offset, start;
	vec3_t	forward, right;
	int		damage;
	float	damage_radius = 1000;

	AngleVectors (ent->client->v_angle, forward, right, NULL);
	VectorScale (forward, -2, ent->client->kick_origin);

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

	if(ent->client->ps.gunframe == 9)
	{
		ent->flags &= ~FL_BFGMISSFIRE;
	}

  if(!(ent->flags & FL_BFGMISSFIRE) && EMPNukeCheck(ent, start))
  {
		ent->flags |= FL_BFGMISSFIRE;
		gi.sound (ent, CHAN_AUTO, gi.soundindex("items/empnuke/emp_missfire.wav"), 1, ATTN_NORM, 0);
  }

	if(ent->flags & FL_BFGMISSFIRE)
	{
		ent->client->ps.gunframe++;
		return;
	}

	if (deathmatch->value)
		damage = 200;
	else
		damage = 500;

	if (ent->client->ps.gunframe == 9)
	{
		// send muzzle flash
		gi.WriteByte (svc_muzzleflash);
		gi.WriteShort (ent-g_edicts);
		gi.WriteByte (MZ_BFG | is_silenced);
		gi.multicast (ent->s.origin, MULTICAST_PVS);

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

		PlayerNoise(ent, start, PNOISE_WEAPON);
		return;
	}

	// cells can go down during windup (from power armor hits), so
	// check again and abort firing if we don't have enough now
	if (ent->client->pers.inventory[ent->client->ammo_index] < 50)
	{
		ent->client->ps.gunframe++;
		return;
	}

	if (is_quad)
		damage *= 4;


	// make a big pitch kick with an inverse fall
	ent->client->v_dmg_pitch = -40;
	ent->client->v_dmg_roll = crandom()*8;
	ent->client->v_dmg_time = level.time + DAMAGE_TIME;

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

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

	fire_bfg (ent, start, forward, damage, 400, damage_radius);

	PlayerNoise(ent, start, PNOISE_WEAPON);

	// play quad damage sound
	playQuadSound(ent);
}
예제 #19
0
파일: weapon.c 프로젝트: phine4s/xatrix
void
weapon_phalanx_fire(edict_t *ent)
{
	vec3_t start;
	vec3_t forward, right, up;
	vec3_t offset;
	vec3_t v;
	int damage;
	float damage_radius;
	int radius_damage;

  	if (!ent)
	{
		return;
	}

	damage = 70 + (int)(random() * 10.0);
	radius_damage = 120;
	damage_radius = 120;

	if (is_quad)
	{
		damage *= 4;
		radius_damage *= 4;
	}

	AngleVectors(ent->client->v_angle, forward, right, NULL);

	VectorScale(forward, -2, ent->client->kick_origin);
	ent->client->kick_angles[0] = -2;

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

	if (ent->client->ps.gunframe == 8)
	{
		v[PITCH] = ent->client->v_angle[PITCH];
		v[YAW] = ent->client->v_angle[YAW] - 1.5;
		v[ROLL] = ent->client->v_angle[ROLL];
		AngleVectors(v, forward, right, up);

		radius_damage = 30;
		damage_radius = 120;

		fire_plasma(ent, start, forward, damage, 725,
				damage_radius, radius_damage);

		if (!((int)dmflags->value & DF_INFINITE_AMMO))
		{
			ent->client->pers.inventory[ent->client->ammo_index]--;
		}
	}
	else
	{
		v[PITCH] = ent->client->v_angle[PITCH];
		v[YAW] = ent->client->v_angle[YAW] + 1.5;
		v[ROLL] = ent->client->v_angle[ROLL];
		AngleVectors(v, forward, right, up);
		fire_plasma(ent, start, forward, damage, 725,
				damage_radius, radius_damage);

		/* send muzzle flash */
		gi.WriteByte(svc_muzzleflash);
		gi.WriteShort(ent - g_edicts);
		gi.WriteByte(MZ_PHALANX | is_silenced);
		gi.multicast(ent->s.origin, MULTICAST_PVS);

		PlayerNoise(ent, start, PNOISE_WEAPON);
	}

	ent->client->ps.gunframe++;
}
예제 #20
0
/*
=================
fire_lead

This is an internal support routine used for bullet/pellet based weapons.
=================
*/
static void fire_lead(edict_t * self, vec3_t start, vec3_t aimdir, int damage, int kick, int te_impact, int hspread, int vspread, int mod)
{
    trace_t tr;
    vec3_t dir;
    vec3_t forward, right, up;
    vec3_t end;
    float r;
    float u;
    vec3_t water_start;
    qboolean water = false;
    int content_mask = MASK_SHOT | MASK_WATER;

    tr = gi.trace(self->s.origin, NULL, NULL, start, self, MASK_SHOT);
    if (!(tr.fraction < 1.0))
    {
        vectoangles(aimdir, dir);
        AngleVectors(dir, forward, right, up);

        r = crandom() * hspread;
        u = crandom() * vspread;
        VectorMA(start, 8192, forward, end);
        VectorMA(end, r, right, end);
        VectorMA(end, u, up, end);

        if (gi.pointcontents(start) & MASK_WATER)
        {
            water = true;
            VectorCopy(start, water_start);
            content_mask &= ~MASK_WATER;
        }

        tr = gi.trace(start, NULL, NULL, end, self, content_mask);

        // see if we hit water
        if (tr.contents & MASK_WATER)
        {
            int color;

            water = true;
            VectorCopy(tr.endpos, water_start);

            if (!VectorCompare(start, tr.endpos))
            {
                if (tr.contents & CONTENTS_WATER)
                {
                    if (strcmp(tr.surface->name, "*brwater") == 0)
                        color = SPLASH_BROWN_WATER;
                    else
                        color = SPLASH_BLUE_WATER;
                }
                else if (tr.contents & CONTENTS_SLIME)
                    color = SPLASH_SLIME;
                else if (tr.contents & CONTENTS_LAVA)
                    color = SPLASH_LAVA;
                else
                    color = SPLASH_UNKNOWN;

                if (color != SPLASH_UNKNOWN)
                {
                    gi.WriteByte(svc_temp_entity);
                    gi.WriteByte(TE_SPLASH);
                    gi.WriteByte(8);
                    gi.WritePosition(tr.endpos);
                    gi.WriteDir(tr.plane.normal);
                    gi.WriteByte(color);
                    gi.multicast(tr.endpos, MULTICAST_PVS);
                }

                // change bullet's course when it enters water
                VectorSubtract(end, start, dir);
                vectoangles(dir, dir);
                AngleVectors(dir, forward, right, up);
                r = crandom() * hspread * 2;
                u = crandom() * vspread * 2;
                VectorMA(water_start, 8192, forward, end);
                VectorMA(end, r, right, end);
                VectorMA(end, u, up, end);
            }

            // re-trace ignoring water this time
            tr = gi.trace(water_start, NULL, NULL, end, self, MASK_SHOT);
        }
    }

    // send gun puff / flash
    if (!((tr.surface) && (tr.surface->flags & SURF_SKY)))
    {
        if (tr.fraction < 1.0)
        {
            if (tr.ent->takedamage)
            {
                T_Damage(tr.ent, self, self, aimdir, tr.endpos, tr.plane.normal, damage, kick, DAMAGE_BULLET, mod);
            }
            else
            {
                if (strncmp(tr.surface->name, "sky", 3) != 0)
                {
                    gi.WriteByte(svc_temp_entity);
                    gi.WriteByte(te_impact);
                    gi.WritePosition(tr.endpos);
                    gi.WriteDir(tr.plane.normal);
                    gi.multicast(tr.endpos, MULTICAST_PVS);

                    if (self->client)
                        PlayerNoise(self, tr.endpos, PNOISE_IMPACT);
                }
            }
        }
    }

    // if went through water, determine where the end and make a bubble trail
    if (water)
    {
        vec3_t pos;

        VectorSubtract(tr.endpos, water_start, dir);
        VectorNormalize(dir);
        VectorMA(tr.endpos, -2, dir, pos);
        if (gi.pointcontents(pos) & MASK_WATER)
            VectorCopy(pos, tr.endpos);
        else
            tr = gi.trace(pos, NULL, NULL, water_start, tr.ent, MASK_WATER);

        VectorAdd(water_start, tr.endpos, pos);
        VectorScale(pos, 0.5, pos);

        gi.WriteByte(svc_temp_entity);
        gi.WriteByte(TE_BUBBLETRAIL);
        gi.WritePosition(water_start);
        gi.WritePosition(tr.endpos);
        gi.multicast(pos, MULTICAST_PVS);
    }
}
예제 #21
0
/*
 * Fires a single blaster bolt.
 * Used by the blaster and hyper blaster.
 */
void
blaster_touch(edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
{
	int mod;

	if (!self || !other || !plane || !surf)
	{
		G_FreeEdict(self);
		return;
	}

	if (other == self->owner)
	{
		return;
	}

	if (surf->flags & SURF_SKY)
	{
		G_FreeEdict(self);
		return;
	}

	if (self->owner->client)
	{
		PlayerNoise(self->owner, self->s.origin, PNOISE_IMPACT);
	}

	if (other->takedamage)
	{
		if (self->spawnflags & 1)
		{
			mod = MOD_HYPERBLASTER;
		}
		else
		{
			mod = MOD_BLASTER;
		}

		T_Damage(other, self, self->owner, self->velocity, self->s.origin,
				plane->normal, self->dmg, 1, DAMAGE_ENERGY, mod);
	}
	else
	{
		gi.WriteByte(svc_temp_entity);
		gi.WriteByte(TE_BLASTER);
		gi.WritePosition(self->s.origin);

		if (!plane)
		{
			gi.WriteDir(vec3_origin);
		}
		else
		{
			gi.WriteDir(plane->normal);
		}

		gi.multicast(self->s.origin, MULTICAST_PVS);
	}

	G_FreeEdict(self);
}
예제 #22
0
void Chaingun_Fire (edict_t *ent)
{
	int			shots, flash_shots = 1;
	vec3_t		start;
	vec3_t		forward, right, up;
	float		r, u;
	vec3_t		offset;
	int			damage;
	int			kick = 0;
	int item = getWornItem(ent, GIEX_ITEM_WEAPON);
	iteminfo_t	*info = getWornItemInfo(ent, 0);
	int	i, spread = getMachinegunSpread(ent, item, info);

//	damage = info->arg1 + info->arg2 * ent->client->pers.skill[1];
	damage = getChaingunDamage(ent, item, info);

	if (ent->client->ps.gunframe == 5) {
		if ((ent->client->silencer_shots > 0) && (ent->client->pers.skill[58] > 6)) {
			ent->client->silencer_shots -= 1;
		} else {
			gi.sound(ent, CHAN_AUTO, gi.soundindex("weapons/chngnu1a.wav"), 1, ATTN_IDLE, 0);
		}
		ent->client->ps.gunframe += ent->client->pers.skill[5];
	}

	if ((ent->client->ps.gunframe == 14) && !(ent->client->buttons & BUTTON_ATTACK)) {
		ent->client->ps.gunframe = 32; // End firing
		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; // Loop back
	} else {
		ent->client->ps.gunframe++;
	}

	if (ent->client->ps.gunframe == 22) {
		ent->client->weapon_sound = 0;
		if ((ent->client->silencer_shots > 0) && (ent->client->pers.skill[58] > 6)) {
			ent->client->silencer_shots -= 1;
		} else {
			gi.sound(ent, CHAN_AUTO, gi.soundindex("weapons/chngnd1a.wav"), 1, ATTN_IDLE, 0);
		}
		ent->client->ps.gunframe += ent->client->pers.skill[5];
	} else {
		if ((ent->client->silencer_shots > 0) && (ent->client->pers.skill[58] > 6)) {
			ent->client->silencer_shots -= 1;
		} 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 = info->arg4;
	} else if (ent->client->ps.gunframe <= 14) {
		if (ent->client->buttons & BUTTON_ATTACK) {
			shots = info->arg4 + 1; flash_shots = 2;
		} else {
			shots = info->arg4; flash_shots = 1;
		}
	}
	else { // 15 - 20
		if ((ent->client->ps.gunframe == 18) || (ent->client->ps.gunframe == 20)) {
			shots = info->arg4 + 2; flash_shots = 2;
		} else {
			shots = info->arg4 + 1; flash_shots = 1;
		}
	}

	if (shots < 1)
		shots = 1;
	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) {
			gi.sound(ent, CHAN_VOICE, gi.soundindex("weapons/noammo.wav"), 1, ATTN_NORM, 0);
			ent->pain_debounce_time = level.time + 1;
		}
		NoAmmoWeaponChange (ent);
		return;
	}

	damage = applyWeaponBonuses(ent, damage, 1);
//	if (is_quad)
//		kick *= 4;

	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, spread, spread, MOD_CHAINGUN);
	}

	// send muzzle flash
	if ((ent->client->silencer_shots > 0) && (ent->client->pers.skill[58] > 7)) {
		ent->client->silencer_shots -= shots;
	} else {
		gi.WriteByte (svc_muzzleflash);
		gi.WriteShort (ent-g_edicts);
		gi.WriteByte ((MZ_CHAINGUN1 + flash_shots) | is_silenced);
		gi.multicast (ent->s.origin, MULTICAST_PVS);
	}

	ent->client->silencer_shots-=3;
	PlayerNoise(ent, start, PNOISE_WEAPON);

//	if (! ( (int)dmflags->value & DF_INFINITE_AMMO ) )
		ent->client->pers.inventory[ent->client->ammo_index] -= shots;
}
예제 #23
0
void
Grenade_Explode(edict_t *ent)
{
	vec3_t origin;
	int mod;

	if (!ent)
	{
		return;
	}

	if (ent->owner && ent->owner->client)
	{
		PlayerNoise(ent->owner, ent->s.origin, PNOISE_IMPACT);
	}

	if (ent->enemy)
	{
		float points;
		vec3_t v;
		vec3_t dir;

		VectorAdd(ent->enemy->mins, ent->enemy->maxs, v);
		VectorMA(ent->enemy->s.origin, 0.5, v, v);
		VectorSubtract(ent->s.origin, v, v);
		points = ent->dmg - 0.5 * VectorLength(v);
		VectorSubtract(ent->enemy->s.origin, ent->s.origin, dir);

		if (ent->spawnflags & 1)
		{
			mod = MOD_HANDGRENADE;
		}
		else
		{
			mod = MOD_GRENADE;
		}

		T_Damage(ent->enemy, ent, ent->owner, dir, ent->s.origin, vec3_origin,
				(int)points, (int)points, DAMAGE_RADIUS, mod);
	}

	if (ent->spawnflags & 2)
	{
		mod = MOD_HELD_GRENADE;
	}
	else if (ent->spawnflags & 1)
	{
		mod = MOD_HG_SPLASH;
	}
	else
	{
		mod = MOD_G_SPLASH;
	}

	T_RadiusDamage(ent, ent->owner, ent->dmg, ent->enemy, ent->dmg_radius, mod);

	VectorMA(ent->s.origin, -0.02, ent->velocity, origin);
	gi.WriteByte(svc_temp_entity);

	if (ent->waterlevel)
	{
		if (ent->groundentity)
		{
			gi.WriteByte(TE_GRENADE_EXPLOSION_WATER);
		}
		else
		{
			gi.WriteByte(TE_ROCKET_EXPLOSION_WATER);
		}
	}
	else
	{
		if (ent->groundentity)
		{
			gi.WriteByte(TE_GRENADE_EXPLOSION);
		}
		else
		{
			gi.WriteByte(TE_ROCKET_EXPLOSION);
		}
	}

	gi.WritePosition(origin);
	gi.multicast(ent->s.origin, MULTICAST_PHS);

	G_FreeEdict(ent);
}
예제 #24
0
void weapon_arm_fire (edict_t *ent)
{
	vec3_t		start;
	vec3_t		forward, right;
	vec3_t		offset;
	int			damage;
	iteminfo_t	*info = getWornItemInfo(ent, 0);
	int			kick = info->arg9;
	int			refire = info->arg3 + 2;
	int			recycle = info->arg4 + 1;
	int			range = info->arg5;
	int			count = info->arg6;// + (int) (info->arg6 * ent->client->pers.skill[3]);
	int			cost = info->arg10;

	if (refire < 2)
		refire = 2;
	if (recycle < 1)
		recycle = 1;

	cost *= ((float) (ent->client->max_magic + 1200.0)) / 1200.0;

	damage = (int) ceil(info->arg1 + info->arg2 * (float) ent->client->pers.skill[1]);

	if ((!(ent->client->buttons & BUTTON_ATTACK)) || (ent->client->magic < cost)) {
		ent->client->ps.gunframe = 9 + recycle;
		return;
	}
	ent->client->magic -= cost;
	if (ent->client->magregentime < level.time + 0.5)
		ent->client->magregentime = level.time + 0.5;

/*	if (ent->client->ps.gunframe == 9) {
		ent->client->ps.gunframe++;
		return;
	}*/

	AngleVectors (ent->client->v_angle, forward, right, NULL);

	VectorScale (forward, -2, ent->client->kick_origin);
	ent->client->kick_angles[0] = -2;

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

	damage = applyWeaponBonuses(ent, damage, count);
	if (is_quad)
		kick *= 4;

	fire_armblast(ent, start, forward, damage, kick, info->arg7, info->arg8, count, range, MOD_ARM);
	ent->client->silencer_shots-=4;

	// send muzzle flash
	if ((ent->client->silencer_shots > 0) && (ent->client->pers.skill[58] > 7)) {
		ent->client->silencer_shots -= 1;
	} else {
		gi.sound(ent, CHAN_AUTO, gi.soundindex("parasite/paratck2.wav"), 1, ATTN_NORM, 0);
		gi.WriteByte (svc_muzzleflash);
		gi.WriteShort (ent-g_edicts);
		gi.WriteByte (MZ_NUKE1);
		gi.multicast (ent->s.origin, MULTICAST_PVS);

/*		gi.WriteByte (svc_muzzleflash);
		gi.WriteShort (ent-g_edicts);
		gi.WriteByte (MZ_SHOTGUN | is_silenced);
		gi.multicast (ent->s.origin, MULTICAST_PVS);*/
	}

	if ((ent->client->ps.gunframe == 9) && (ent->client->buttons & BUTTON_ATTACK)) {
		ent->client->ps.gunframe -= refire;
	}
	ent->client->ps.gunframe++;

//	if (!(ent->client->buttons & BUTTON_ATTACK))
//		ent->client->ps.gunframe += recycle;
	PlayerNoise(ent, start, PNOISE_WEAPON);

//	if (! ( (int)dmflags->value & DF_INFINITE_AMMO ) )
		ent->client->pers.inventory[ent->client->ammo_index]--;
}
예제 #25
0
void
rocket_touch(edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf)
{
	vec3_t origin;
	int n;

	if (!ent || !other || !plane || !surf)
	{
		G_FreeEdict(ent);
		return;
	}

	if (other == ent->owner)
	{
		return;
	}

	if (surf->flags & SURF_SKY)
	{
		G_FreeEdict(ent);
		return;
	}

	if (ent->owner && ent->owner->client)
	{
		PlayerNoise(ent->owner, ent->s.origin, PNOISE_IMPACT);
	}

	/* calculate position for the explosion entity */
	VectorMA(ent->s.origin, -0.02, ent->velocity, origin);

	if (other->takedamage)
	{
		T_Damage(other, ent, ent->owner, ent->velocity, ent->s.origin,
				plane->normal, ent->dmg, 0, 0, MOD_ROCKET);
	}
	else
	{
		/* don't throw any debris in net games */
		if (!deathmatch->value && !coop->value)
		{
			if ((surf) && !(surf->flags &
				  (SURF_WARP | SURF_TRANS33 | SURF_TRANS66 | SURF_FLOWING)))
			{
				n = randk() % 5;

				while (n--)
				{
					ThrowDebris(ent, "models/objects/debris2/tris.md2",
							2, ent->s.origin);
				}
			}
		}
	}

	T_RadiusDamage(ent, ent->owner, ent->radius_dmg, other, ent->dmg_radius,
			MOD_R_SPLASH);

	gi.WriteByte(svc_temp_entity);

	if (ent->waterlevel)
	{
		gi.WriteByte(TE_ROCKET_EXPLOSION_WATER);
	}
	else
	{
		gi.WriteByte(TE_ROCKET_EXPLOSION);
	}

	gi.WritePosition(origin);
	gi.multicast(ent->s.origin, MULTICAST_PHS);

	G_FreeEdict(ent);
}
예제 #26
0
/*
=============
P_WorldEffects
=============
*/
void P_WorldEffects (void)
{
	qboolean	breather;
	qboolean	envirosuit;
	int			waterlevel, old_waterlevel;

	if (current_player->movetype == MOVETYPE_NOCLIP)
	{
		current_player->air_finished = level.time + 12;	// don't need air
		return;
	}

	//K03 Begin
	//if (HasActiveCurse(current_player, CURSE_FROZEN))
	if (que_typeexists(current_player->curses, CURSE_FROZEN))
		current_player->air_finished = level.time + 6;
	//K03 End

	waterlevel = current_player->waterlevel;
	old_waterlevel = current_client->old_waterlevel;
	current_client->old_waterlevel = waterlevel;

	breather = current_client->breather_framenum > level.framenum;
	envirosuit = current_client->enviro_framenum > level.framenum;

	//
	// if just entered a water volume, play a sound
	//
	if (!old_waterlevel && waterlevel)
	{
		if ((current_player->client->pers.inventory[ITEM_INDEX(FindItem("Stealth Boots"))] < 1))
		{
			if((current_player->myskills.abilities[CLOAK].disable) || (current_player->myskills.abilities[CLOAK].current_level))
			{
				current_player->lastsound = level.framenum; // trigger monsters
				PlayerNoise(current_player, current_player->s.origin, PNOISE_SELF);
				if (current_player->watertype & CONTENTS_LAVA)
					gi.sound (current_player, CHAN_BODY, gi.soundindex("player/lava_in.wav"), 1, ATTN_NORM, 0);
				else if (current_player->watertype & CONTENTS_SLIME)
					gi.sound (current_player, CHAN_BODY, gi.soundindex("player/watr_in.wav"), 1, ATTN_NORM, 0);
				else if (current_player->watertype & CONTENTS_WATER)
					gi.sound (current_player, CHAN_BODY, gi.soundindex("player/watr_in.wav"), 1, ATTN_NORM, 0);
			}
		}
		current_player->flags |= FL_INWATER;

		// clear damage_debounce, so the pain sound will play immediately
		current_player->damage_debounce_time = level.time - 1;
	}

	//
	// if just completely exited a water volume, play a sound
	//
	if (old_waterlevel && ! waterlevel)
	{
		if ((current_player->client->pers.inventory[ITEM_INDEX(FindItem("Stealth Boots"))]<1) && !current_player->mtype)
		{
			if((current_player->myskills.abilities[CLOAK].disable) || (current_player->myskills.abilities[CLOAK].current_level < 1))
			{
				current_player->lastsound = level.framenum; // trigger monsters
				PlayerNoise(current_player, current_player->s.origin, PNOISE_SELF);
				gi.sound (current_player, CHAN_BODY, gi.soundindex("player/watr_out.wav"), 1, ATTN_NORM, 0);
			}
		}
		current_player->flags &= ~FL_INWATER;
	}

	//
	// check for head just going under water
	//
	if (old_waterlevel != 3 && waterlevel == 3)
	{
		if (current_player->client)//K03
			gi.sound (current_player, CHAN_BODY, gi.soundindex("player/watr_un.wav"), 1, ATTN_NORM, 0);
	}

	//
	// check for head just coming out of water
	//
	if (old_waterlevel == 3 && waterlevel != 3)
	{
		if (current_player->air_finished < level.time)
		{	// gasp for air
			if (current_player->client)//K03
			{
			gi.sound (current_player, CHAN_VOICE, gi.soundindex("player/gasp1.wav"), 1, ATTN_NORM, 0);
			PlayerNoise(current_player, current_player->s.origin, PNOISE_SELF);
			}
		}
		else  if (current_player->air_finished < level.time + 11)
		{	// just break surface
			if (current_player->client)//K03
				gi.sound (current_player, CHAN_VOICE, gi.soundindex("player/gasp2.wav"), 1, ATTN_NORM, 0);
		}
	}

	//
	// check for drowning
	//
	if (waterlevel == 3)
	{
		// breather or envirosuit give air
		if (breather || envirosuit)
		{
			current_player->air_finished = level.time + 10;

			if (((int)(current_client->breather_framenum - level.framenum) % 25) == 0)
			{
				if (current_player->client)//K03
				{
				if (!current_client->breather_sound)
					gi.sound (current_player, CHAN_AUTO, gi.soundindex("player/u_breath1.wav"), 1, ATTN_NORM, 0);
				else
					gi.sound (current_player, CHAN_AUTO, gi.soundindex("player/u_breath2.wav"), 1, ATTN_NORM, 0);
				current_client->breather_sound ^= 1;
				PlayerNoise(current_player, current_player->s.origin, PNOISE_SELF);
				}
				//FIXME: release a bubble?
			}
		}

		// if out of air, start drowning
		if ((current_player->air_finished < level.time) 
			&& !((current_player->myskills.class_num == CLASS_POLTERGEIST) && (current_player->mtype == 0))
			&& (current_player->myskills.abilities[WORLD_RESIST].current_level < 1 
									|| HasFlag(current_player)) 
			&& !(current_player->flags & FL_GODMODE))
		{	// drown!
			if (current_player->client->next_drown_time < level.time 
				&& current_player->health > 0)
			{
				current_player->client->next_drown_time = level.time + 1;

				// take more damage the longer underwater
				current_player->dmg += 2;
				if (current_player->dmg > 15)
					current_player->dmg = 15;

				// play a gurp sound instead of a normal pain sound
				if (current_player->client)
				{
					if (current_player->health <= current_player->dmg)
						gi.sound (current_player, CHAN_VOICE, gi.soundindex("player/drown1.wav"), 1, ATTN_NORM, 0);
					else if (rand()&1)
						gi.sound (current_player, CHAN_VOICE, gi.soundindex("*gurp1.wav"), 1, ATTN_NORM, 0);
					else
						gi.sound (current_player, CHAN_VOICE, gi.soundindex("*gurp2.wav"), 1, ATTN_NORM, 0);
				}

				current_player->pain_debounce_time = level.time;

				T_Damage (current_player, world, world, vec3_origin, current_player->s.origin, vec3_origin, current_player->dmg, 0, DAMAGE_NO_ARMOR, MOD_WATER);
			}
		}
	}
	else
	{
		current_player->air_finished = level.time + 12;
		current_player->dmg = 2;
	}

	//
	// check for sizzle damage
	//
	if (waterlevel && (current_player->watertype & (CONTENTS_LAVA|CONTENTS_SLIME)) 
		&& (current_player->myskills.abilities[WORLD_RESIST].current_level < 1 || HasFlag(current_player)) 
		&& !(current_player->flags & FL_GODMODE) 
		&& !((current_player->myskills.class_num == CLASS_POLTERGEIST) && (current_player->mtype == 0)))
	{
		if (current_player->watertype & CONTENTS_LAVA)
		{
			if (current_player->health > 0
				&& current_player->pain_debounce_time <= level.time
				&& current_client->invincible_framenum < level.framenum)
			{
				if (current_player->client)//K03
				{
				if (rand()&1)
					gi.sound (current_player, CHAN_VOICE, gi.soundindex("player/burn1.wav"), 1, ATTN_NORM, 0);
				else
					gi.sound (current_player, CHAN_VOICE, gi.soundindex("player/burn2.wav"), 1, ATTN_NORM, 0);
				}
				current_player->pain_debounce_time = level.time + 1;
			}

			if (envirosuit)	// take 1/3 damage with envirosuit
				T_Damage (current_player, world, world, vec3_origin, current_player->s.origin, vec3_origin, 1*waterlevel, 0, 0, MOD_LAVA);
			else
				T_Damage (current_player, world, world, vec3_origin, current_player->s.origin, vec3_origin, 3*waterlevel, 0, 0, MOD_LAVA);
		}

		if (current_player->watertype & CONTENTS_SLIME)
		{
			if (!envirosuit)
			{	// no damage from slime with envirosuit
				T_Damage (current_player, world, world, vec3_origin, current_player->s.origin, vec3_origin, 1*waterlevel, 0, 0, MOD_SLIME);
			}
		}
	}
}
예제 #27
0
파일: weapon.c 프로젝트: greck2908/qengine
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;
  }
}