//////////////////////////////////////////////////////////////////////////////////
//
//	DoD Shell Shock
//		- Version 0.8
//		- 06.09.2006
//		- diamond-optic (original code by v3x)
//
//////////////////////////////////////////////////////////////////////////////////
//
// Credit:
//
//   - Original Code by v3x (he_damage_effect v0.2)
//   - http://www.amxmodx.org/forums/viewtopic.php?t=25271
//   - Ported to DoD by diamond-optic
//   - cadav0r: fade & shake CVAR code, new volume fx method, and various other fixes
//   - WARDOG: new ringing sound
//
// Information:
//
//   - When you take damage from grenades or rockets, your
//     screen will be distorted & you're sound volume
//     will decrease for a few seconds before it returns
//     to normal. There is also a ringing sound thats played.
//     I dont really know how to best explain this....
//   - Minimum damage required is controlled by cvars
//     for each one of the effects...
//   - Each effect is also controlled by cvars (on/off)
//
//   - The fov effect isnt finished yet, therefor it defualts
//     to '0' (off) but I left the code here incase anyone
//     else wants to play around with it...
//
// CVARS:
//
//   dod_shellshock "1" //Turn on(1)/off(0)
//
//   dod_shellshock_fade "1" //Turn on(1)/off(0) quick screen fade
//   dod_shellshock_fade_dmg "25" //Sets the minimum damage required
//
//   dod_shellshock_shake "1" //Turn on(1)/off(0) screen shake
//   dod_shellshock_shake_dmg "40" //Sets the minimum damage required
//
//   dod_shellshock_volume "1" //Turn on(1)/off(0) short volume loss
//   dod_shellshock_volume_dmg "40" //Sets the minimum damage required
//   dod_shellshock_volume_time1 "10" //How long you lose volume (10ths of a second)
//   dod_shellshock_volume_time2 "5" //Delay between each volume increase step (10ths of a second)
//
//   dod_shellshock_ring "1" //Turn on(1)/off(0) ringing effect
//   dod_shellshock_ring_dmg "50" //Sets the minimum damage required
//
//   dod_shellshock_fov "0" //Turn on(1)/off(0) fov effect (unfinished)
//   dod_shellshock_fov_dmg "90" //Sets the minimum damage required
//
// Extra:
//
//      Put the "shellshock_ring3.mp3" in /dod/sound/misc/  
//
// Changelog:
//
//   - 05.01.2006 Version 0.1
//  	  Initial port of v3x's "he_damage_effect v0.2"
//  	  Added cvar to set min. dmg required
//	  Added Rockets as well as grenades
//
//   - 05.03.2006 Version 0.2
//  	  Added Garand & K43 buttstocks
//
//   - 05.05.2006 Version 0.3
//        Added CVAR for buttstocks
//	  Renamed to DoD Shell Shock
//
//   - 05.06.2006 Version 0.4
//        Removed buttstocks till I do it a better way
//        Changed from MSG_ONE to MSG_ONE_UNRELIABLE
//
//   - 05.10.2006 Version 0.5
//        Added CVARs for fade & shake (code from cadav0r)
//	  Added CVAR for volume
//
//   - 05.12.2006 Version 0.6
//        CVAR query bug fixed (thanks cadav0r)
//	  New method for volume effect (thanks cadav0r)
//	  Fixed volume staying at 0.0 bug
//
//   - 05.15.2006 Version 0.7
//	  Another fix for CVAR query problem
//        Added ringing sound MP3 (still plays during volume effect)
//	  Added CVAR for ringing effect
//	  Added FOV effect (defualts to 0 as im not satisfied with it yet)
//
//   - 05.18.2006 Version 0.7b
//	  Removed global damage cvar and added one for each effect
//
//   - 05.22.2006 Version 0.7c
//	  Fixed run-time error
//	  Adjusted a few random things...
//
//   - 05.24.2006 Version 0.7d
//	  Fixed 2 small errors becuase of my stupidity (thanks cadav0r)
//
//   - 06.09.2006 Version 0.8
//	  Added CVAR for how long you lose your volume
//	  Added CVAR for delay between each volume increase step (thanks cadav0r)
//	  New 'ringing' sound (thanks WARDOG)
//	  Adjusted ScreenFade & ScreenShake message variables
//
//////////////////////////////////////////////////////////////////////////////////

#include <amxmodx>
#include <engine>
#include <dodx>
#include <fun>

new gMsgScreenShake , gMsgScreenFade, gMsgSetFOV, p_dod_shellshock
new p_dod_shellshock_fade, p_dod_shellshock_shake, p_dod_shellshock_volume, p_dod_shellshock_volume_time1, p_dod_shellshock_volume_time2, p_dod_shellshock_ring, p_dod_shellshock_fov
new p_dod_shellshock_fade_dmg, p_dod_shellshock_shake_dmg, p_dod_shellshock_volume_dmg, p_dod_shellshock_ring_dmg, p_dod_shellshock_fov_dmg

public plugin_init() {
  register_plugin("DoD Shell Shock" , "0.8" , "AMXX DoD Team & v3x")
  p_dod_shellshock = register_cvar("dod_shellshock", "1")
  //fade
  p_dod_shellshock_fade = register_cvar("dod_shellshock_fade", "1")
  p_dod_shellshock_fade_dmg = register_cvar("dod_shellshock_fade_dmg", "25")
  //shake 
  p_dod_shellshock_shake = register_cvar("dod_shellshock_shake", "1")
  p_dod_shellshock_shake_dmg = register_cvar("dod_shellshock_shake_dmg", "40")
  //volume
  p_dod_shellshock_volume = register_cvar("dod_shellshock_volume", "1")
  p_dod_shellshock_volume_dmg = register_cvar("dod_shellshock_volume_dmg", "50")
  p_dod_shellshock_volume_time1 = register_cvar("dod_shellshock_volume_time1", "10") //10ths of a second
  p_dod_shellshock_volume_time2 = register_cvar("dod_shellshock_volume_time2", "5") //10ths of a second
  //ring
  p_dod_shellshock_ring = register_cvar("dod_shellshock_ring", "1")
  p_dod_shellshock_ring_dmg = register_cvar("dod_shellshock_ring_dmg", "75")
  //fov
  p_dod_shellshock_fov = register_cvar("dod_shellshock_fov", "0")
  p_dod_shellshock_fov_dmg = register_cvar("dod_shellshock_fov_dmg", "99")  
    
  gMsgScreenShake = get_user_msgid("ScreenShake")
  gMsgScreenFade = get_user_msgid("ScreenFade")
  gMsgSetFOV = get_user_msgid("SetFOV")
  register_statsfwd(XMF_DAMAGE)
}

#define PA_LOW  30.0
#define PA_HIGH 60.0

new Float:gVolume[33], volumeup[33], gFov[33]

public plugin_precache() {

  precache_sound("misc/shellshock_ring_3.mp3")
}

public client_putinserver(id) {
  
  if (!is_user_bot(id) && is_user_connected(id) && get_pcvar_num(p_dod_shellshock) == 1)
	{ 
	set_task(10.0, "cvar_query", id)
	}
}

public cvar_query(id) {		//added this func to fix cvar query bug

  if (!is_user_bot(id) && is_user_connected(id) && get_pcvar_num(p_dod_shellshock) == 1)
	{
	query_client_cvar(id , "volume" , "cvar_result")
	volumeup[id] = 0
	}
}

public cvar_result(id, const cvar[] , const value[]) {
  
  if (!is_user_bot(id) && is_user_connected(id) && get_pcvar_num(p_dod_shellshock) == 1)
	{
	if (gVolume[id] == 0)
		{
		gVolume[id] = 1.0
		}	
	gVolume[id] = str_to_float(value)
	}
}

public client_damage(attacker,victim,damage,wpnindex,hitplace,TA){

  if(get_pcvar_num(p_dod_shellshock) != 1 || !is_user_connected(victim) || !is_user_alive(victim) || is_user_bot(victim))
	return PLUGIN_HANDLED

  if(wpnindex == DODW_MILLS_BOMB || wpnindex == DODW_HANDGRENADE || wpnindex == DODW_HANDGRENADE_EX || wpnindex == DODW_STICKGRENADE || wpnindex == DODW_STICKGRENADE_EX || wpnindex == DODW_PIAT || wpnindex == DODW_BAZOOKA || wpnindex == DODW_PANZERSCHRECK){
    
  if(get_pcvar_num(p_dod_shellshock_ring) == 1 && damage >= get_pcvar_num(p_dod_shellshock_ring_dmg))
	{
	client_cmd(victim,"mp3 play sound/misc/shellshock_ring_3")
	}
    
  if(get_pcvar_num(p_dod_shellshock_volume) == 1 && damage >= get_pcvar_num(p_dod_shellshock_volume_dmg))
	{
	client_cmd(victim , "volume 0")
	
	new Float: noVolume, Float:ten
	ten = str_to_float("10")
	noVolume = get_pcvar_float(p_dod_shellshock_volume_time1)
	
	if (noVolume < 1.0)
		{
		noVolume = 1.0
		}
	
	noVolume = floatdiv(Float:noVolume, Float:ten)
	
	set_task(noVolume, "volume_up" , victim)
	}
	
  if(get_pcvar_num(p_dod_shellshock_shake) == 1 && damage >= get_pcvar_num(p_dod_shellshock_shake_dmg))
	{ 
	
	new Float:fVec[3];
	fVec[0] = random_float(PA_LOW , PA_HIGH)
	fVec[1] = random_float(PA_LOW , PA_HIGH)
	fVec[2] = random_float(PA_LOW , PA_HIGH)
	entity_set_vector(victim , EV_VEC_punchangle , fVec)
    
	message_begin(MSG_ONE_UNRELIABLE , gMsgScreenShake , {0,0,0} ,victim)
	write_short(1<<14) //ammount 
	write_short(1<<12) //lasts this long 
	write_short(2<<14) //frequency
	message_end()
	}
	
  if(get_pcvar_num(p_dod_shellshock_fade) == 1 && damage >= get_pcvar_num(p_dod_shellshock_fade_dmg))
	{
	message_begin(MSG_ONE_UNRELIABLE , gMsgScreenFade , {0,0,0} , victim)
	write_short(1<<13)  //duraiton  (old - 1<<11)
	write_short(1<<12)  //hold time  (old - 1<<10)
	write_short(0x0002)  //flags  (old - 1<<12)
	write_byte(225) //red
	write_byte(0) //green
	write_byte(0) //blue
	write_byte(160) //alpha
	message_end()
	}
	
  if(get_pcvar_num(p_dod_shellshock_fov) == 1 && damage >= get_pcvar_num(p_dod_shellshock_fov_dmg))
	{
	message_begin(MSG_ONE_UNRELIABLE, gMsgSetFOV, {0,0,0}, victim)
	write_byte(170)
	message_end() 
	
	gFov[victim] = 170
	set_task(0.5 , "reset_fov" , victim)
	}
  }
  return PLUGIN_HANDLED
}

public volume_up(id) {

  if(is_user_bot(id) || !is_user_connected(id))
	return PLUGIN_HANDLED
  
  new Float:set_value, valuestr[5], valuenum, Float:ten, Float: set_time
  valuenum = volumeup[id] + 1
  num_to_str(valuenum, valuestr, 4)
  set_value = str_to_float(valuestr)
  ten = str_to_float("10")
  set_value = floatdiv(Float:set_value, Float:ten)

  set_time = get_pcvar_float(p_dod_shellshock_volume_time2)
 
  if (set_time < 1.0)
	{
	set_time = 1.0
	}
	
  set_time = floatdiv(Float:set_time, Float:ten)
    
  if(set_value < gVolume[id]) 
	{
	client_cmd(id , "volume %f", set_value)
	++volumeup[id]
	set_task(set_time, "volume_up", id)
	} 
  else
	{
	client_cmd(id , "volume %f" , gVolume[id])
	volumeup[id] = 0
	}
  return PLUGIN_HANDLED
}

public reset_fov(id) {

  if (is_user_bot(id) || !is_user_connected(id))
	return PLUGIN_HANDLED
    
  gFov[id] = gFov[id] - 5

  if(gFov[id] > 90) 
	{	
	message_begin(MSG_ONE_UNRELIABLE, gMsgSetFOV, {0,0,0}, id)
	write_byte(gFov[id])
	message_end()
	
	set_task(0.2, "reset_fov", id)
	} 
  else
	{ 
	message_begin(MSG_ONE_UNRELIABLE, gMsgSetFOV, {0,0,0}, id)
	write_byte(90)
	message_end()
	}
  return PLUGIN_HANDLED
}
