/* AMX Mod X
*   Fall Scream
*
* (c) Copyright 2006 by VEN
*
* This file is provided as is (no warranties)
*
*     REQUESTED by lastchapter
*
*     PLUGIN provides global fall scream sound
*
*     FAKEMETA module required
*
*     VERSIONS
*       0.2   - added "regular" fall support
*             - improved custom sound support
*             - improved vertigo-style maps detection
*             - few optimizations
*       0.1   - first release
*/

#include <amxmodx>
#include <fakemeta>

#define PLUGIN_NAME "Fall Scream"
#define PLUGIN_VERSION "0.2"
#define PLUGIN_AUTHOR "VEN"

// OPTIONS BELOW

// comment to disable outside-map-fall scream (building, abyss, etc)
// note: that option fully independent from SCREAM_FALL_SPEED value
#define SCREAM_VERTIGO_STYLE

// player's minimal fall speed required for scream sound playback
#define SCREAM_FALL_SPEED 700

// scream sound filename, may be changed to custom sound file
#define SOUND_FILE "ambience/fallscream.wav"

// scream sound volume, min. = 0, max. = 10
#define SOUND_VOLUME 10

// OPTIONS ABOVE

#define FLAG_EVERYWHERE (1<<0)
#define FLAG_START_SILENT (1<<4)
#define FLAG_NOT_LOOPING (1<<5)

#define SOUND_FLAGS (FLAG_EVERYWHERE | FLAG_START_SILENT | FLAG_NOT_LOOPING)

new ENT_INDEX

#define MAXPLAYERS 32
new bool:g_can_scream[MAXPLAYERS + 1]

public plugin_precache() {
	precache_sound(SOUND_FILE)
}

public plugin_init() {
	register_plugin(PLUGIN_NAME, PLUGIN_VERSION, PLUGIN_AUTHOR)

	new ent = -1, message[24]
	new string_class[] = "classname"
	new entity_class[] = "ambient_generic"
	new sound_default[] = "ambience/fallscream.wav"
	while ((ent = engfunc(EngFunc_FindEntityByString, ent, string_class, entity_class))) {
		pev(ent, pev_message, message, 23)
		if (equali(message, sound_default))
			return
	}

	ENT_INDEX = engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, entity_class))
	set_pev(ENT_INDEX, pev_health, float(SOUND_VOLUME))
	set_pev(ENT_INDEX, pev_message, SOUND_FILE)
	set_pev(ENT_INDEX, pev_spawnflags, SOUND_FLAGS)
	dllfunc(DLLFunc_Spawn, ENT_INDEX)

	register_forward(FM_PlayerPreThink, "forward_player_prethink")

#if !defined SCREAM_VERTIGO_STYLE
}

#else
	if (!engfunc(EngFunc_FindEntityByString, -1, string_class, "trigger_hurt"))
		return

	// since on de_vertigo map fall scream sound emits almost at the time when player dies
	// we disregard that insignificant delay - implementation would not worth a methods
	// v0.2 note: i tried to implement that delay and realized that there are no good ways
	register_event("DeathMsg", "event_vertigo_scream", "a", "1=0", "2!0", "4=trigger_hurt")
}

public event_vertigo_scream() {
	new id = read_data(2)
	if (g_can_scream[id])
		dllfunc(DLLFunc_Use, ENT_INDEX, id)
}

#endif

public forward_player_prethink(id) {
	if (!is_user_alive(id))
		return FMRES_IGNORED

	// not a typo: integer
	new fvel = pev(id, pev_flFallVelocity)

	if (g_can_scream[id]) {
		if (fvel >= SCREAM_FALL_SPEED) {
			g_can_scream[id] = false
			dllfunc(DLLFunc_Use, ENT_INDEX, id)
		}
	}
	else if (!fvel)
		g_can_scream[id] = true

	return FMRES_IGNORED
}
