Health Armor Stations плъгина да не ти прави 100 кръвта, когато имаш над 100 и използваш станция

В този раздел можете да подавате всякакви заявки за намиране, изработка или преработка на плъгини/модове.
Аватар
LoShIaA
Извън линия
Потребител
Потребител
Мнения: 323
Регистриран на: 20 Окт 2016, 14:44
Местоположение: Стара Загора
Се отблагодари: 120 пъти
Получена благодарност: 9 пъти

Health Armor Stations плъгина да не ти прави 100 кръвта, когато имаш над 100 и използваш станция

Мнение от LoShIaA » 22 Окт 2017, 18:38

Здравейте. Проблема е същия (viewtopic.php?f=54&t=2398), но при друг плъгин. Имам шоп и като имам примерно 150 кръв след като заредя на станция кръвта става на 100, същото важи и за бронята. Ще е добре да се направи някаква проверка, ако имаш над 100 кръв и като натиснеш станцията тя да не зарежда.
Кода:

Код за потвърждение: Избери целия код

/**********************************************************************************
* 									Health/Armor-Stations
*
*
* Author: regalis ([email protected])
*
*
*	Version: 0.3.5
*
*
*
*	Description:
*		Do you know HalfLife Deathmatch?
*		There are Stations to recharge your Health and you Armor.
*		Now you can have these Station in Counterstrike too!
*		Place the Stations you want where you want ;)
*
*		To place a Station make sure you are an admin and bind a key to "+place_station".
*		Now press the key and aim at where you want to place the station, release the key to choose which sort of station you want to place.
*		With the commands "push_station" and "pull_station" you can pull or push the station in the direction you are looking.
*		If you have choosen the station which fits your needs you can save it to the config-file which is automaticaly created for each map.
*		That all...
*		To use these Stations just stand near it and press your USE-key (standard: E)
*		The reloading of the Station is triggered as soon as the Station gets empty!
*
*
*
*
*	Admin-Commands:
*		"+place_station" - Place an Health/Armor-Station on the wall in front of you
*		"push_station" - Move the Health/Armor-Station away of you
*		"pull_station" - Move the Health/Armor-Station closer to you
*		"del_station" - Delete the Healt/Armor-Station at which you aim
*
*
*
* CVARS:
*		HA_maxhealth - How much health is in a HealthStation for everyone [number of HP](0-100) (Default: 40 HP)
*		HA_maxplayerhealth - Set the maximum amount of health a player can charge [100 - 255] (Default: 255 HP)
*		HA_healthpersec - Set the amount of HP a player get per chargecycle [1 - ?] (Default: 4 HP should be 8-12 HP per second) 
*		HA_maxarmor - How much armor is in a ArmorStation for everyone [number of AP]	(0-100)	(Default: 40 AP)
*		HA_maxplayerarmor - Set the maximum amount of armor a player can charge [100 - 255] (Default: 255 AP)
*		HA_armorpersec - Set the amount of AP a player get per chargecycle [1 - ?] (Default: 4 AP should be 8-12 AP per second)
*		HA_healthreloadtime - How long the player have to wait till he can use the same HealthStation again [number in seconds](Default: 30 sec)
*		HA_armorreloadtime - How long the player have to wait till he can use the same ArmorStation again [number in seconds]	(Default: 30 sec)
*		HA_gloweffect - Let the HealthStations glow red and the ArmorStations glow blue [0|1]	(on|off) (Default: 1)
*		
*
*
*	Requirements:
*		Fakemeta-Modul
*
*
*
*	Changelog:
*		v0.1:
*			@ initial release
*
*		v0.2:
*			! Fixed a sound bug
*			+ Added support for newly placed station giving HP/AP
*			+ Added 4 new CVARS for more customization
*
*		v0.3:
*			- Removed static declaration for global Variables
*			- Removed "stock" for functions
*			+ Added a function to delete placed stations
*			+ Added real armor to the stations (only for Counterstrike)
*		
*		v0.3.1:
*			! fixed a bug with realarmor(it is only for CounterStrike)
*
*		v0.3.5:
*			!fixed a bug when you placed a station at the sky/ceiling the server crashed...now it is handled
*
*
* Known Bugs:
*		- At some placing angles the station looks black
*			(Workaround: Just place it from another angle)
*
*
*	TODO:
*		- maybe optimizing a little
*
*
*	Credits:
*		stupok69 for his nice In-Game-Ads where i have taken the Station placing (http://forums.alliedmods.net/showthread.php?p=424583)
*		Cheap_suit for his help here: (http://forums.alliedmods.net/showpost.php?p=482976&postcount=4)
*		Alka for the help on fixing the bug with the "placing at the sky/ceiling"
*		Simon Logic for his idea with Armour-Absence-Fix Plugin here: (http://forums.alliedmods.net/showthread.php?t=55591)
*		VEN for his fakemeta_util.inc here: (http://forums.alliedmods.net/showthread.php?t=28284)
*		PM for his xs.inc
*
*
***********************************************************************************/
#include <amxmodx>
#include <amxmisc>
#include <fakemeta>


//++++++++++++++++++++
//+++++ DEFINES ++++++
//++++++++++++++++++++
// Define the offset for the Armor manipulation stock
#if cellbits == 32
	#define OFFSET_ARMORTYPE 112
#else
	#define OFFSET_ARMORTYPE 137
#endif
#define OFFSET_LINUX 5

#define CONFIGFOLDER "HA-Stations"
#define PLACESTEPFREQUENCY 10
#define DISTANCE 3.0
#define ADMIN_ACCESS_LEVEL ADMIN_BAN
#define MAXPLAYERS 32
#define MAXMEDKITS 15
#define MAXRECHARGES 15
#define MEDKITCLASS "ha_medkit"
#define RECHARGECLASS "ha_recharge"
#define SND_STOP (1<<5)

// Define the Author :P 
#define PLUGIN "Healt&Armor-Stations"
#define VERSION "0.3.5"
#define AUTHOR "regalis"


//+++++++++++++++++++++++++++++
//+++++ GLOBAL VARIABLES ++++++
//+++++++++++++++++++++++++++++
// The models
new const g_models[][] =
{
	"models/stz/HealthArmor-Stations/HealthStation.mdl",
	"models/stz/HealthArmor-Stations/ArmorStation.mdl"
}
new const gModelIndex = sizeof g_models;

// The Glow colors
new const Float:g_colors[][3] = {
	{255.0, 0.0, 0.0},
	{0.0, 0.0, 255.0}
}

// ################## FOR FUTURE USAGE #################
//new static bool:g_restart_attempt[33];
// ################## FOR FUTURE USAGE #################


//+++++ MESSAGE IDs ++++++
new g_umsgA;
//new g_msgM;
	
	
//+++++ Adminstuff + Filehandling +++++
new g_prethink_placestepper;
new g_curmodeltype;
new g_entity;
new g_curAdjuster = -1;
new Float:g_aimOrigin[3][3];
new Float:g_entity_angles[3];
new g_file_name[256]
new g_map_name[32];
new bool:g_adjusting = false;

//+++++ Deleting +++++
new g_del_num;
new g_del_models[MAXMEDKITS+MAXRECHARGES];
new Float:g_del_origins[MAXMEDKITS+MAXRECHARGES][3];
new Float:g_del_angles[MAXMEDKITS+MAXRECHARGES][3];

//+++++ Checking the usage +++++
new Float:g_nextstep[MAXPLAYERS+1];
new Float:g_chargesteppfrequency = 0.5;
new bool:g_faraway;
new g_cvar_gloweffect;

// Medkit
new Float:g_medkit_coords[MAXMEDKITS][3];
new Float:g_medkit_angles[MAXMEDKITS][3];
new g_medkit_id[MAXMEDKITS];
new g_medkit_count;

// Recharge
new Float:g_recharge_coords[MAXRECHARGES][3];
new Float:g_recharge_angles[MAXRECHARGES][3];
new g_recharge_id[MAXRECHARGES];
new g_recharge_count;


//+++++ Healthhandling +++++
new g_medkit_value[MAXMEDKITS][MAXPLAYERS+1];
new bool:g_snd_medkit[MAXMEDKITS][MAXPLAYERS+1];
new g_cvar_maxhealth;
new g_cvar_maxplayerhealth;
new g_cvar_healthpersec
new Float:g_cvar_medkitreloadtime;
new g_pHealth[MAXPLAYERS+1];


//+++++ Armorhandling +++++
new g_recharge_value[MAXRECHARGES][MAXPLAYERS+1];
new bool:g_snd_recharge[MAXRECHARGES][MAXPLAYERS+1];
new g_cvar_maxarmor;
new g_cvar_maxplayerarmor;
new g_cvar_armorpersec;
new Float:g_cvar_rechargereloadtime;
new g_pArmor[MAXPLAYERS+1];


//+++++ GLOBAL CVAR POINTER ++++++
new gcvar_maxhealth;
new gcvar_maxplayerhealth;
new gcvar_medkitreloadtime;
new gcvar_healthpersec
new gcvar_maxarmor;
new gcvar_maxplayerarmor;
new gcvar_rechargereloadtime;
new gcvar_armorpersec;
new gcvar_gloweffect;



//++++++++++++++++++++++++
//+++++ PLUGIN-INIT ++++++
//++++++++++++++++++++++++
public plugin_init()
{
	register_plugin(PLUGIN, VERSION, AUTHOR);
	register_cvar(PLUGIN, VERSION, FCVAR_SERVER);
	
	//+++++ cvar pointer ++++++
	gcvar_maxhealth = register_cvar("HA_maxhealth", "40");
	gcvar_maxplayerhealth = register_cvar("HA_maxplayerhealth", "100");
	gcvar_healthpersec = register_cvar("HA_healthpersec", "2")
	gcvar_maxarmor = register_cvar("HA_maxarmor", "40");
	gcvar_maxplayerarmor = register_cvar("HA_maxplayerarmor", "100");
	gcvar_armorpersec = register_cvar("HA_armorpersec", "2");
	gcvar_medkitreloadtime = register_cvar("HA_healthreloadtime", "20");
	gcvar_rechargereloadtime = register_cvar("HA_armorreloadtime", "20");
	gcvar_gloweffect = register_cvar("HA_gloweffect", "1");
	
	//+++++ Admin Commands +++++
	register_clcmd("+place_station", "cmd_place_station", ADMIN_ACCESS_LEVEL);
	register_clcmd("-place_station", "cmd_place_station", ADMIN_ACCESS_LEVEL);
	register_clcmd("pull_station", "pull_station", ADMIN_ACCESS_LEVEL);
	register_clcmd("push_station", "push_station", ADMIN_ACCESS_LEVEL);
	register_clcmd("del_station", "del_station", ADMIN_ACCESS_LEVEL);
	
	//+++++ Menu Commands +++++
	register_menucmd(register_menuid("save_menu"), (1<<0)|(1<<1), "action_save");
	register_menucmd(register_menuid("select_menu"), 1023, "action_select");
	
	//################## FOR FUTURE USAGE #################
	/*
	//+++++ Client Commands ++++++
	register_clcmd("fullupdate", "clcmd_fullupdate");
	//+++++ Events ++++++
	register_event("ResetHUD", "event_hud_reset", "be");
	register_event("TextMsg", "event_restart_attempt", "a", "2=#Game_will_restart_in");
	*/
	//################## FOR FUTURE USAGE #################
	
	//+++++ Message ID +++++
	g_umsgA = get_user_msgid("ArmorType");
	//g_umsgM = get_user_msgid("Money");
	
	//+++++ Logevents ++++++
	register_logevent("event_roundStart", 2, "1=Round_Start");
	register_logevent("event_round_end", 2, "1=Round_End");
	
	//+++++ Forwards +++++
	register_forward(FM_PlayerPreThink, "PreThink");
	
	//+++++ Read the Config +++++
	readCvars();
	
	//+++++ Load the saved Stations +++++
	load_saved_stations(g_file_name);
}



//++++++++++++++++++++++++++++
//+++++ PLUGIN-PRECACHE ++++++
//++++++++++++++++++++++++++++
public plugin_precache()
{
	new configs_dir[64];
	get_configsdir(configs_dir, 63);
	get_mapname(g_map_name, 31);
	
	// Save the Configfilename in a global variable
	formatex(g_file_name, 255, "%s/%s", configs_dir, CONFIGFOLDER);
	if(!dir_exists(g_file_name)) mkdir(g_file_name);
	formatex(g_file_name, 255, "%s/%s/%s.txt", configs_dir, CONFIGFOLDER, g_map_name);
	
	// Precache the models
	for(new m = 0; m < gModelIndex; m++) engfunc(EngFunc_PrecacheModel,g_models[m]);
	
	
	// Precache the sounds
	precache_sound("stz/HealthArmor-Stations/ArmorRecharge.wav");
	precache_sound("stz/HealthArmor-Stations/ArmorRechargeOk.wav");
	precache_sound("stz/HealthArmor-Stations/ArmorRechargeNo.wav");
	precache_sound("stz/HealthArmor-Stations/HealthRecharge.wav");
	precache_sound("stz/HealthArmor-Stations/HealthRechargeOk.wav");
	precache_sound("stz/HealthArmor-Stations/HealthRechargeNo.wav");
}




//*****************************************************************************************************************
//****************************************   G E N E R A L S T U F F   ********************************************
//*****************************************************************************************************************

//################## FOR FUTURE USAGE #################
/* 
//+++++ CLIENT COMMAND FULLUPDATE ++++++
public clcmd_fullupdate()
{
	return PLUGIN_HANDLED_MAIN;
}

//+++++ Event RESTART-ATTEMPT ++++++
public event_restart_attempt()
{
	new players[32], num;
	get_players(players, num, "a");
	for (new i; i < num; ++i)
	{
		g_restart_attempt[players[i]] = true;
	}
}

//+++++ Event HUD-RESET ++++++
public event_hud_reset(id)
{
	if (g_restart_attempt[id])
	{
		g_restart_attempt[id] = false;
		return;
	}
	event_player_spawn(id);
}

//+++++ Event PLAYERSPAWN ++++++
public event_player_spawn(id)
{
	// nothing to do...maybe later ;)
}
*/
//################## FOR FUTURE USAGE #################

//+++++ Event ROUNDSTART ++++++
public event_roundStart()
{
	readCvars();
	resetStations();
}

public event_round_end()
{
	resetStations();
}

//+++++ READ THE CVARS +++++++
readCvars()
{
	// Putting the CVARS in the global variables
	g_cvar_maxarmor = get_pcvar_num(gcvar_maxarmor);
	g_cvar_maxplayerarmor = get_pcvar_num(gcvar_maxplayerarmor);
	g_cvar_armorpersec = get_pcvar_num(gcvar_armorpersec);
	g_cvar_maxhealth = get_pcvar_num(gcvar_maxhealth);
	g_cvar_maxplayerhealth = get_pcvar_num(gcvar_maxplayerhealth);
	g_cvar_healthpersec = get_pcvar_num(gcvar_healthpersec);
	g_cvar_rechargereloadtime = get_pcvar_float(gcvar_rechargereloadtime);
	g_cvar_medkitreloadtime = get_pcvar_float(gcvar_medkitreloadtime);
	g_cvar_gloweffect = get_pcvar_num(gcvar_gloweffect);
}



//*****************************************************************************************************************
//*****************************************   S T A T I O N H A N D L I N G   *************************************
//*****************************************************************************************************************

//+++++ RESET THE STATIONS +++++++
resetStations()
{
	for (new i=0; i < 32; i++)
	{
		// Reset medkit-Stations to the cvar value
		for(new m = 0; m < g_medkit_count; m++)
		{
			if(task_exists(434774+i+m))	 remove_task(434774+i+m);
			g_medkit_value[m][i] = g_cvar_maxhealth;
			if(g_snd_medkit[m][i])
			{
				emit_sound(g_medkit_id[m], CHAN_WEAPON, "stz/HealthArmor-Stations/HealthRecharge.wav", 1.0, ATTN_NORM, SND_STOP, PITCH_NORM);
				g_snd_medkit[m][i] = false;
			}
		}
		
		// Reset recharge-Stations to the cvar value
		for(new r = 0; r < g_recharge_count; r++)
		{
			if(task_exists(477434+i+r))	 remove_task(477434+i+r);
			g_recharge_value[r][i] = g_cvar_maxarmor;
			if(g_snd_recharge[r][i])
			{
				emit_sound(g_recharge_id[r], CHAN_WEAPON, "stz/HealthArmor-Stations/ArmorRecharge.wav", 1.0, ATTN_NORM, SND_STOP, PITCH_NORM);
				g_snd_recharge[r][i] = false;
			}
		}
	}
}


//+++++ RESET A HEALTH STATION +++++
public reset_HealthStation(param[2])
{
	// Get the params
	new id = param[0];
	new number = param[1];
	
	// Reset the value of the certain Station to the value stored in the cvar
	g_medkit_value[number][id] = g_cvar_maxhealth;
}


//+++++ RESET A ARMOR STATION +++++
public reset_ArmorStation(param[2])
{
	// Get the params
	new id = param[0];
	new number = param[1];
	
	// Reset the value of the certain Station to the value stored in the cvar
	g_recharge_value[number][id] = g_cvar_maxarmor;
}


remove_stations()
{
	new ent = -1;
	while((ent = engfunc(EngFunc_FindEntityByString, -1, "classname", MEDKITCLASS)) != 0)
	{
		if(pev_valid(ent))
		{
			engfunc(EngFunc_RemoveEntity, ent);
		}
	}
	ent = -1;
	while((ent = engfunc(EngFunc_FindEntityByString, -1, "classname", RECHARGECLASS)) != 0)
	{
		if(pev_valid(ent))
		{
			engfunc(EngFunc_RemoveEntity, ent);
		}
	}
	g_del_num = 0;
	g_medkit_count = 0;
	g_recharge_count = 0;
}


//*****************************************************************************************************************
//********************************   H E A L T H - A R M O R H A N D L I N G  *************************************
//*****************************************************************************************************************

//+++++ Give the player health +++++
GiveHealth(id, number)
{
	if(g_medkit_value[number][id] > 0)
	{
		// The HealthValue in the current station for this player is more than 0
		g_pHealth[id] = pev(id, pev_health); // Get the player health
		if(g_pHealth[id] <= g_cvar_maxplayerhealth-g_cvar_healthpersec)
		{
			g_medkit_value[number][id] -= g_cvar_healthpersec; // subtract the given Healthvalue from the Health-Station value
			set_pev(id, pev_health, float(g_pHealth[id]+g_cvar_healthpersec)); // Give the player the Health
			if(!g_snd_medkit[number][id])
			{
				emit_sound(g_medkit_id[number], CHAN_WEAPON, "stz/HealthArmor-Stations/HealthRecharge.wav", 1.0, ATTN_NORM, 0, PITCH_NORM);
			}
		}
		else
		{
			if(g_pHealth[id] == g_cvar_maxplayerhealth)
			{
				emit_sound(g_medkit_id[number], CHAN_WEAPON, "stz/HealthArmor-Stations/HealthRecharge.wav", 1.0, ATTN_NORM, SND_STOP, PITCH_NORM);
				emit_sound(g_medkit_id[number], CHAN_STREAM, "stz/HealthArmor-Stations/HealthRechargeNo.wav", 1.0, ATTN_NORM, 0, PITCH_NORM);
			}
			else
			{
				set_pev(id, pev_health, float(g_cvar_maxplayerhealth));
				emit_sound(g_medkit_id[number], CHAN_WEAPON, "stz/HealthArmor-Stations/HealthRecharge.wav", 1.0, ATTN_NORM, SND_STOP, PITCH_NORM);
				emit_sound(id, CHAN_STREAM, "stz/HealthArmor-Stations/HealthRechargeOk.wav", 1.0, ATTN_NORM, 0, PITCH_NORM);
			}
		}
	}
	else
	{
		emit_sound(g_medkit_id[number], CHAN_WEAPON, "stz/HealthArmor-Stations/HealthRecharge.wav", 1.0, ATTN_NORM, SND_STOP, PITCH_NORM);
		emit_sound(g_medkit_id[number], CHAN_STREAM, "stz/HealthArmor-Stations/HealthRechargeNo.wav", 1.0, ATTN_NORM, 0, PITCH_NORM);
		// Health-Station is empty
		if(!task_exists(434774+id+number))
		{
			new param[2];
			param[0] = id;
			param[1] = number;
			// Plan a task to refresh the Health-Station value
			set_task(g_cvar_medkitreloadtime, "reset_HealthStation", 434774+id+number, param, 2);
		}
	}
}

//+++++ Give the player armor +++++
GiveArmor(id, number)
{
	if(g_recharge_value[number][id] > 0)
	{
		// The ArmorValue in the current station for this player is more than 0
		g_pArmor[id] = pev(id, pev_armorvalue); // Get the player armor
		if(g_pArmor[id] <= g_cvar_maxplayerarmor-g_cvar_armorpersec)
		{
			// Player have a lower ArmorValue than 100
			g_recharge_value[number][id] -= g_cvar_armorpersec;	// Subtract the given armor from the Armor-Station value
			if(!get_pdata_int(id, OFFSET_ARMORTYPE, OFFSET_LINUX)) set_realarmor(id);
			set_pev(id, pev_armorvalue, float(g_pArmor[id]+g_cvar_armorpersec)); // Give the player the Armor
			
			if(!g_snd_recharge[number][id])
			{
				emit_sound(g_recharge_id[number], CHAN_WEAPON, "stz/HealthArmor-Stations/ArmorRecharge.wav", 1.0, ATTN_NORM, 0, PITCH_NORM);
			}
		}
		else
		{
			if(g_pArmor[id] == g_cvar_maxplayerarmor)
			{
				emit_sound(g_recharge_id[number], CHAN_WEAPON, "stz/HealthArmor-Stations/ArmorRecharge.wav", 1.0, ATTN_NORM, SND_STOP, PITCH_NORM);
				emit_sound(g_recharge_id[number], CHAN_STREAM, "stz/HealthArmor-Stations/ArmorRechargeNo.wav", 1.0, ATTN_NORM, 0, PITCH_NORM);
			}
			else
			{
				set_pev(id, pev_armorvalue, float(g_cvar_maxplayerarmor)); // If player have between 96-100 Armor set it to 100
				emit_sound(g_recharge_id[number], CHAN_WEAPON, "stz/HealthArmor-Stations/ArmorRecharge.wav", 1.0, ATTN_NORM, SND_STOP, PITCH_NORM);
				emit_sound(id, CHAN_STREAM, "stz/HealthArmor-Stations/ArmorRechargeOk.wav", 1.0, ATTN_NORM, 0, PITCH_NORM);
			}
		}
	}
	else
	{
		emit_sound(g_recharge_id[number], CHAN_WEAPON, "stz/HealthArmor-Stations/ArmorRecharge.wav", 1.0, ATTN_NORM, SND_STOP, PITCH_NORM);
		emit_sound(g_recharge_id[number], CHAN_STREAM, "stz/HealthArmor-Stations/ArmorRechargeNo.wav", 1.0, ATTN_NORM, 0, PITCH_NORM);
		// Armor-Station is empty
		if(!task_exists(477434+id+number))
		{
			new param[2];
			param[0] = id;
			param[1] = number;
			// Plan a task to refresh the Armor-Station value
			set_task(g_cvar_rechargereloadtime, "reset_ArmorStation", 477434+id+number, param, 2);
		}
	}
}


//*****************************************************************************************************************
//*****************************************   F I L E H A N D L I N G   *******************************************
//*****************************************************************************************************************

//+++++ SAVE POSITION TO FILE ++++++
public save_pos()
{
	new text[256];
	
	get_configsdir(g_file_name, 255);
	format(g_file_name, 255, "%s/%s/%s.txt", g_file_name, CONFIGFOLDER, g_map_name);
	
	pev(g_entity, pev_angles, g_entity_angles);
	formatex(text, 255, "^n%s^norigin %f %f %f^nangles %f %f %f", g_models[g_curmodeltype], g_aimOrigin[2][0], g_aimOrigin[2][1], g_aimOrigin[2][2], g_entity_angles[0], g_entity_angles[1], g_entity_angles[2]);
	write_file(g_file_name, text);
	
	if(g_curmodeltype == 0)
	{
		g_medkit_coords[g_medkit_count][0] = g_aimOrigin[2][0];
		g_medkit_coords[g_medkit_count][1] = g_aimOrigin[2][1];
		g_medkit_coords[g_medkit_count][2] = g_aimOrigin[2][2];
		g_medkit_angles[g_medkit_count][0] = g_entity_angles[0];
		g_medkit_angles[g_medkit_count][1] = g_entity_angles[1];
		g_medkit_angles[g_medkit_count][2] = g_entity_angles[2];
		g_medkit_id[g_medkit_count] = g_entity;
		g_medkit_count++;
	}
	else
	{
		g_recharge_coords[g_recharge_count][0] = g_aimOrigin[2][0];
		g_recharge_coords[g_recharge_count][1] = g_aimOrigin[2][1];
		g_recharge_coords[g_recharge_count][2] = g_aimOrigin[2][2];
		g_recharge_angles[g_recharge_count][0] = g_entity_angles[0];
		g_recharge_angles[g_recharge_count][1] = g_entity_angles[1];
		g_recharge_angles[g_recharge_count][2] = g_entity_angles[2];
		g_recharge_id[g_recharge_count] = g_entity;
		g_recharge_count++;
	}	
	g_entity = 0;
	resetStations();
}

//+++++ LOAD THE SAVED Stations ++++++
load_saved_stations(file_name[])
{
	new lastread = 0;
	new file_handle = fopen(file_name, "r");
	
	if(!file_handle) return PLUGIN_HANDLED;
		
	new file_text[64];
	new ent, str_value[3][16];
	
	while(!feof(file_handle))
	{
		fgets(file_handle, file_text, 63);
		trim(file_text);
		
		if(equal(file_text, "//", 2) || !file_text[0]) continue;
		
		if(contain(file_text, "HealthStation.mdl") != -1)
		{
			if(!file_exists(file_text))
			{
				log_amx("Error: Failed to load HealthStation.mdl, model does not exist.", file_text);
				continue;
			}
			ent = engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, "info_target"));
			engfunc(EngFunc_SetModel, ent, file_text);
			set_pev(ent, pev_classname, MEDKITCLASS);
			set_pev(ent, pev_controller_0, 125);
			set_pev(ent, pev_controller_1, 125);
			set_pev(ent, pev_controller_2, 125);
			set_pev(ent, pev_controller_3, 125);
			set_pev(ent, pev_solid, 2);
			
			setGlow(ent);
			g_medkit_id[g_medkit_count] = ent;
			lastread = 1;
		}
		else if(contain(file_text, "ArmorStation.mdl") != -1)
		{
			if(!file_exists(file_text))
			{
				log_amx("Error: Failed to load ArmorStation.mdl, model does not exist.");
				continue;
			}
			ent = engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, "info_target"));
			engfunc(EngFunc_SetModel, ent, file_text);
			set_pev(ent, pev_classname, RECHARGECLASS);
			set_pev(ent, pev_controller_0, 125);
			set_pev(ent, pev_controller_1, 125);
			set_pev(ent, pev_controller_2, 125);
			set_pev(ent, pev_controller_3, 125);
			set_pev(ent, pev_solid, 2);
			
			setGlow(ent);
			g_recharge_id[g_recharge_count] = ent;
			lastread = 2;
		}
		else if(equal(file_text, "origin", 6))
		{
			parse(file_text[6], str_value[0], 15, str_value[1], 15, str_value[2], 15);
			
			switch(lastread)
			{
				case 1:
				{
					g_medkit_coords[g_medkit_count][0] = str_to_float(str_value[0]);
					g_medkit_coords[g_medkit_count][1] = str_to_float(str_value[1]);
					g_medkit_coords[g_medkit_count][2] = str_to_float(str_value[2]);
					engfunc(EngFunc_SetOrigin, ent, g_medkit_coords[g_medkit_count]);
				}
				case 2:
				{
					g_recharge_coords[g_recharge_count][0] = str_to_float(str_value[0]);
					g_recharge_coords[g_recharge_count][1] = str_to_float(str_value[1]);
					g_recharge_coords[g_recharge_count][2] = str_to_float(str_value[2]);
					engfunc(EngFunc_SetOrigin, ent, g_recharge_coords[g_recharge_count]);					
				}
			}		
		}
		else if(equal(file_text, "angles", 6))
		{
			parse(file_text[6], str_value[0], 15, str_value[1], 15, str_value[2], 15);
			
			switch(lastread)
			{
				case 1:
				{
					g_medkit_angles[g_medkit_count][0] = str_to_float(str_value[0]);
					g_medkit_angles[g_medkit_count][1] = str_to_float(str_value[1]);
					g_medkit_angles[g_medkit_count][2] = str_to_float(str_value[2]);
					set_pev(ent, pev_angles, g_medkit_angles[g_medkit_count]);
					
					new Float:mins[3] = {-2.0, -2.0, 38.0};
					new Float:maxs[3] = {2.0, 2.0, 42.0};
					engfunc(EngFunc_SetSize, ent, mins, maxs);
					g_medkit_count++;
				}
				case 2:
				{
					g_recharge_angles[g_recharge_count][0] = str_to_float(str_value[0]);
					g_recharge_angles[g_recharge_count][1] = str_to_float(str_value[1]);
					g_recharge_angles[g_recharge_count][2] = str_to_float(str_value[2]);
					set_pev(ent, pev_angles, g_recharge_angles[g_recharge_count]);
					
					new Float:mins[3] = {-2.0, -2.0, 38.0};
					new Float:maxs[3] = {2.0, 2.0, 42.0};
					engfunc(EngFunc_SetSize, ent, mins, maxs);
					g_recharge_count++;
				}
			}	
			lastread = 0;
		}
	}
	fclose(file_handle);
	resetStations();
	return PLUGIN_HANDLED;
}



delete_saved_stations(num, del_class)
{
	get_configsdir(g_file_name, 255);
	format(g_file_name, 255, "%s/%s/%s.txt", g_file_name, CONFIGFOLDER, g_map_name);
	new file_handle = fopen(g_file_name, "r");
	if(!file_handle) return PLUGIN_HANDLED;
	
	new del_medkit_num;
	new del_recharge_num;
	new file_text[64];
	new str_value[3][16];
	
	while(!feof(file_handle))
	{
		fgets(file_handle, file_text, 63);
		trim(file_text);
		
		if(equal(file_text, "//", 2) || !file_text[0]) continue;
		
		if(contain(file_text, "HealthStation.mdl") != -1)
		{
			if(del_medkit_num != num)
			{
				g_del_models[g_del_num] = 0;
				del_medkit_num++;
			}
			else if(del_class == 1)
			{
				fgets(file_handle, file_text, 63);
				fgets(file_handle, file_text, 63);
				del_medkit_num++;
			}
			else
			{
				g_del_models[g_del_num] = 0;
				del_medkit_num++;
			}
		}
		
		else if(contain(file_text, "ArmorStation.mdl") != -1)
		{
			if(del_recharge_num != num)
			{
				g_del_models[g_del_num] = 1;
				del_recharge_num++;
			}
			else if(del_class == 2)
			{
				fgets(file_handle, file_text, 63);
				fgets(file_handle, file_text, 63);
				del_recharge_num++;
			}
			else
			{
				g_del_models[g_del_num] = 1;
				del_recharge_num++;
			}
		}
		
		else if(equal(file_text, "origin", 6))
		{
			parse(file_text[6], str_value[0], 15, str_value[1], 15, str_value[2], 15);
			g_del_origins[g_del_num][0] = str_to_float(str_value[0]);
			g_del_origins[g_del_num][1] = str_to_float(str_value[1]);
			g_del_origins[g_del_num][2] = str_to_float(str_value[2]);
		}
		
		else if(equal(file_text, "angles", 6))
		{
			parse(file_text[6], str_value[0], 15, str_value[1], 15, str_value[2], 15);
			g_del_angles[g_del_num][0] = str_to_float(str_value[0]);
			g_del_angles[g_del_num][1] = str_to_float(str_value[1]);
			g_del_angles[g_del_num][2] = str_to_float(str_value[2]);
			g_del_num++;
		}
	}
	
	fclose(file_handle);
	save_stations_again();
	
	return PLUGIN_HANDLED;
}


public save_stations_again()
{
	new text[256];	
	get_configsdir(g_file_name, 255);
	format(g_file_name, 255, "%s/%s/%s.txt", g_file_name, CONFIGFOLDER, g_map_name);
	new tmpfile = fopen(g_file_name,"w");
	
	for(new i = 0; i < g_del_num; ++i)
	{
		formatex(text, 255, "^n%s^norigin %f %f %f^nangles %f %f %f^n", g_models[g_del_models[i]], g_del_origins[i][0], g_del_origins[i][1], g_del_origins[i][2], g_del_angles[i][0], g_del_angles[i][1], g_del_angles[i][2]);
		fputs(tmpfile,text);
	}
	
	fclose(tmpfile);
	resetStations();
	remove_stations();
	load_saved_stations(g_file_name);
}



//*****************************************************************************************************************
//*********************************************   P R E T H I N K  ************************************************
//*****************************************************************************************************************

public PreThink(id)
{
	//+++++ PLACING STUFF (ADMIN) +++++
	if(g_adjusting && id == g_curAdjuster)
	{
		if(g_prethink_placestepper++ > PLACESTEPFREQUENCY)
		{
			if(!is_aiming_at_sky(id))
			{
				get_aim_origin(id, g_aimOrigin[2]);
	
				if(equal_f(g_aimOrigin[1], g_aimOrigin[2]) < 3)
				{
					if(pev_valid(g_entity))
					{
						engfunc(EngFunc_SetOrigin, g_entity, g_aimOrigin[2]);
						move_station(id, 3);
						
						static Float:normal[3], Float:player_origin[3], Float:test_origin[3];
						
						normal = cross_product(diff_f(g_aimOrigin[0], g_aimOrigin[1]), diff_f(g_aimOrigin[2], g_aimOrigin[1]));
						vector_to_angle(normal, g_entity_angles);
						
						minimize_normal(normal);
						test_origin = sum_f(g_aimOrigin[2], normal);
						pev(id, pev_origin, player_origin);
						
						if(get_distance_f(player_origin, test_origin) > get_distance_f(player_origin, g_aimOrigin[2]))
						{
							set_pev(g_entity, pev_angles, g_entity_angles);
						}
					}	
				}
				if(equal_f(g_aimOrigin[1], g_aimOrigin[2]) < 2 && get_distance_f(g_aimOrigin[2], g_aimOrigin[1]) > 5.0)
				{
					g_aimOrigin[0] = g_aimOrigin[1];
					g_aimOrigin[1] = g_aimOrigin[2];
				}
				g_prethink_placestepper = 0;
			}
		}
	}
	//+++++###+++++ CHECKING STUFF (STATIONS) +++++###+++++
	new Float:gametime = get_gametime();
	if(g_nextstep[id] < gametime)		// is it time for the next check?
	{		
		//~~ Check medkit-Stationstatus ~~
		for(new m = 0; m < g_medkit_count; m++)
		{
			if(pev_valid(g_medkit_id[m]))
			{
				if(ent_distance(id, g_medkit_id[m]) < 30)
				{
					// Player is near a Health-Station
					g_faraway = false;
					if(is_in_viewcone(id, g_medkit_coords[m]))
					{
						// Player is looking at a Health-Station
						if(pev(id, pev_button) & IN_USE)
						{
							// Player is pressing USE-button near a Health-Station
							GiveHealth(id, m);
							g_snd_medkit[m][id] = true;
						}
						else if(g_snd_medkit[m][id] == true)
						{
							emit_sound(g_medkit_id[m], CHAN_WEAPON, "stz/HealthArmor-Stations/HealthRecharge.wav", 1.0, ATTN_NORM, SND_STOP, PITCH_NORM);
							g_snd_medkit[m][id] = false;
						}
					}
					else if(g_snd_medkit[m][id] == true)
					{
						emit_sound(g_medkit_id[m], CHAN_WEAPON, "stz/HealthArmor-Stations/HealthRecharge.wav", 1.0, ATTN_NORM, SND_STOP, PITCH_NORM);
						g_snd_medkit[m][id] = false;
					}
				}
				else
				{
					if(ent_distance(id, g_medkit_id[m]) > 100 && g_faraway)
					{
						g_faraway = true;
						g_snd_medkit[m][id] = false;
					}
					if(g_snd_medkit[m][id] == true) emit_sound(g_medkit_id[m], CHAN_WEAPON, "stz/HealthArmor-Stations/HealthRecharge.wav", 1.0, ATTN_NORM, SND_STOP, PITCH_NORM);
				}
			}
			else
			{
				log_amx("Error: Failure in map config! Please make a new one. (Health-Station nr: %d failed to load)",m);
			}
		}
		//~~ Check recharge-Stationstatus ~~
		for(new r = 0; r < g_recharge_count; r++)
		{
			if(pev_valid(g_recharge_id[r]))
			{
				if(ent_distance(id, g_recharge_id[r]) < 30)
				{
					// Player is near a Recharge-Station
					g_faraway = false;
					if(is_in_viewcone(id, g_recharge_coords[r]))
					{
						// Player is looking at a Recharge-Station
						if(pev(id, pev_button) & IN_USE)
						{
							// Player is pressing USE-Button near a Recharge-Station
							GiveArmor(id, r);
							g_snd_recharge[r][id] = true;							
						}
						else if(g_snd_recharge[r][id] == true)
						{
							emit_sound(g_recharge_id[r], CHAN_WEAPON, "stz/HealthArmor-Stations/ArmorRecharge.wav", 1.0, ATTN_NORM, SND_STOP, PITCH_NORM);
							g_snd_recharge[r][id] = false;
						}
					}
					else if(g_snd_recharge[r][id] == true)
					{
						emit_sound(g_recharge_id[r], CHAN_WEAPON, "stz/HealthArmor-Stations/ArmorRecharge.wav", 1.0, ATTN_NORM, SND_STOP, PITCH_NORM);
						g_snd_recharge[r][id] = false;
					}
				}
				else
				{
					if(ent_distance(id, g_recharge_id[r]) > 100 && g_faraway)
					{
						g_faraway = true;
						g_snd_recharge[r][id] = false;
					}
					if(g_snd_recharge[r][id] == true) emit_sound(g_recharge_id[r], CHAN_WEAPON, "stz/HealthArmor-Stations/ArmorRecharge.wav", 1.0, ATTN_NORM, SND_STOP, PITCH_NORM);
				}
			}
			else
			{
				log_amx("Error: Failure in map config! Please make a new one. (Armor-Station nr: %d failed to load)",r);
			}	
		}
		//~~ Calculate the next Checking time ~~
		if(g_faraway) g_chargesteppfrequency = 1.0;
		else g_chargesteppfrequency = 0.2;
		g_nextstep[id] = gametime + g_chargesteppfrequency; //Add a little delay for checking
		g_faraway = true;
	}
	return FMRES_HANDLED;
}



//*****************************************************************************************************************
//*************************************************   M E N U S   *************************************************
//*****************************************************************************************************************

// Display the Selection Menu
public display_select(id)
{	
	static szMenuBody[224];
	new nKeys;
	if((g_medkit_count < MAXMEDKITS) && (g_recharge_count < MAXRECHARGES))
	{
		nKeys = (1<<9)|(1<<7)|(1<<1)|(1<<0);
		formatex(szMenuBody, 223, "Choose a type: ^n^n1. medkit^n2. recharge^n^n8. Save this Position!^n^n0. Exit");
	}
	else if((g_medkit_count < MAXMEDKITS) && (g_recharge_count == MAXRECHARGES))
	{
		nKeys = (1<<9)|(1<<7)|(1<<1)|(1<<0);
		formatex(szMenuBody, 223, "Choose a type: ^n^n1. medkit^n2. \rrecharge\w^n^n8. Save this Position!^n^n0. Exit");		
	}
	else if((g_recharge_count < MAXRECHARGES) && (g_medkit_count == MAXMEDKITS)) 
	{
		nKeys = (1<<9)|(1<<7)|(1<<1)|(1<<0);
		formatex(szMenuBody, 223, "Choose a type: ^n^n1. \rmedkit\w^n2. recharge^n^n8. Save this Position!^n^n0. Exit");		
	}
	else if((g_medkit_count == MAXMEDKITS) && (g_recharge_count == MAXRECHARGES))
	{
		nKeys = (1<<9)|(1<<7)|(1<<1)|(1<<0);
		formatex(szMenuBody, 223, "You have all available Stations placed!^n^n1. \rmedkit\w^n2. \rrecharge\w^n^n8. \rSave this Position!\w^n^n0. Exit");
	}
	show_menu(id, nKeys, szMenuBody, -1, "select_menu" );
	return;
}

// Check what Key was pressed in the Selection Menu
public action_select(id, key)
{
	switch(key)
	{
		case 0: // medkit
		{
			if(g_medkit_count < MAXMEDKITS && pev_valid(g_entity))
			{
				g_curmodeltype = 0;
				engfunc(EngFunc_SetModel, g_entity, g_models[g_curmodeltype]);
				set_pev(g_entity, pev_classname, MEDKITCLASS);
				new Float:mins[3] = {-2.0, -2.0, 38.0};
				new Float:maxs[3] = {2.0, 2.0, 42.0};
				engfunc(EngFunc_SetSize, g_entity, mins, maxs);
				setGlow(g_entity);
				display_select(id);
			}else display_select(id);
		}
		case 1: // recharge
		{
			if(g_recharge_count < MAXRECHARGES && pev_valid(g_entity))
			{
				g_curmodeltype = 1;
				engfunc(EngFunc_SetModel, g_entity, g_models[g_curmodeltype]);
				set_pev(g_entity, pev_classname, RECHARGECLASS);
				new Float:mins[3] = {-2.0, -2.0, 38.0};
				new Float:maxs[3] = {2.0, 2.0, 42.0};
				engfunc(EngFunc_SetSize, g_entity, mins, maxs);				
				setGlow(g_entity);
				display_select(id);
			}else display_select(id);
		}
		case 7:	
		{
			if((g_recharge_count < MAXRECHARGES) || (g_medkit_count < MAXMEDKITS))
			{
				display_save(id);
			}else	display_select(id);
		}
		case 9:	if(pev_valid(g_entity)) engfunc(EngFunc_RemoveEntity, g_entity);
	}
}

// Display the Save Menu
public display_save(id)
{
	show_menu(id, (1<<0)|(1<<1), "Save this Medkit/Recharger?^n^n1. Yes, save it.^n2. No, delete it.^n", -1, "save_menu");
}

// Check what Key was pressed in the Save Menu
public action_save(id, key)
{
	switch (key)
	{
		case 0: save_pos();
		case 1:
		{
			if(pev_valid(g_entity))
			{
				engfunc(EngFunc_RemoveEntity, g_entity);
			}
		}
	}
}



//*****************************************************************************************************************
//***************************************   E N T I T Y H A N D L I N G   *****************************************
//*****************************************************************************************************************

//+++++ PLACE STATION ++++++
public cmd_place_station(id)
{
	if(!(get_user_flags(id) & ADMIN_ACCESS_LEVEL))
	{
		client_print(id, print_console, "You do not have access to this command.");
		return PLUGIN_HANDLED;
	}
	g_curAdjuster = id;
	new cmd[2];
	read_argv(0, cmd, 1);
	switch(cmd[0])
	{
		case '+':
		{
			if(g_adjusting)
			{
				log_amx("Error: Someone is already placing an Medkit/Recharge");
				client_print(0, print_chat, "Error: Another user is already placing an Medkit/Recharge");
				return PLUGIN_HANDLED;
			}
			if(pev_valid(g_entity)) engfunc(EngFunc_RemoveEntity, g_entity);
			if(!pev_valid(g_entity))
			{
				if(g_medkit_count < MAXMEDKITS || g_recharge_count < MAXRECHARGES) entcreate();
				else
				{
					log_amx("Error: You have placed all available Medkits/Recharges");
					client_print(0, print_chat, "Error: You have placed all available Medkits/Recharges");
					return PLUGIN_HANDLED;
				}
			}
			g_adjusting = true;
		}
		case '-':
		{
			g_adjusting = false;
			if(pev_valid(g_entity) && g_entity != 0) display_select(id);
		}
	}
	return PLUGIN_HANDLED;
}


//+++++ DELETE STATION +++++
public del_station(id)
{
	if(!(get_user_flags(id) & ADMIN_ACCESS_LEVEL))
	{
		client_print(id, print_console, "You do not have access to this command.");
		return PLUGIN_HANDLED;
	}
	
	new ent = get_ent_in_aim_radius(id, 30.0);
	new num = get_station_num(ent);
	
	if(num == -1) return PLUGIN_HANDLED_MAIN;
	
	new class[33];
	pev(ent, pev_classname, class, 32);
	if(equal(class, MEDKITCLASS)) delete_saved_stations(num, 1);
	else delete_saved_stations(num, 2);
	return PLUGIN_CONTINUE;
}


//+++++ CREATE ENTITY ++++++
public entcreate()
{		
	if(g_medkit_count == MAXMEDKITS) g_curmodeltype = 1;
	if(g_recharge_count == MAXRECHARGES) g_curmodeltype = 0;
	
	g_entity = engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, "info_target"));
	engfunc(EngFunc_SetModel, g_entity, g_models[g_curmodeltype]);
	
	if(g_curmodeltype == 0) set_pev(g_entity, pev_classname, MEDKITCLASS);
	else set_pev(g_entity, pev_classname, RECHARGECLASS);
	
	set_pev(g_entity, pev_controller_0, 125);
	set_pev(g_entity, pev_controller_1, 125);
	set_pev(g_entity, pev_controller_2, 125);
	set_pev(g_entity, pev_controller_3, 125);
	
	new Float:mins[3] = {-2.0, -2.0, 38.0};
	new Float:maxs[3] = {2.0, 2.0, 42.0};
	engfunc(EngFunc_SetSize, g_entity, mins, maxs);
	
	set_pev(g_entity, pev_solid, 2);
	
	setGlow(g_entity);
}


//+++++ LET THE STATION GLOW +++++
setGlow(ent)
{
	if(g_cvar_gloweffect && pev_valid(ent))
	{
		new class[32];
		pev(ent, pev_classname, class, 31);
		set_pev(ent, pev_renderfx, kRenderFxHologram);
		if(equal(class, MEDKITCLASS)) set_pev(ent, pev_rendercolor, g_colors[0]); // red for the Medkit-Station
		else set_pev(ent, pev_rendercolor, g_colors[1]); // blue for the Recharge-Station

		set_pev(ent, pev_renderfx, kRenderFxGlowShell);
		set_pev(ent, pev_renderamt, 255.0);
		set_pev(ent, pev_rendermode, kRenderTransAlpha);
	}
}


//+++++ MOVE THE ENTITY ++++++
public pull_station(id)
{
	move_station(id, 1);
}

public push_station(id)
{
	move_station(id, 2);
}

public move_station(id, flag)
{
	if(!(get_user_flags(id) & ADMIN_ACCESS_LEVEL))
	{
		client_print(id, print_console, "You do not have access to this command.");
		return PLUGIN_HANDLED;
	}
	if(pev_valid(g_entity))
	{
		static Float:player_origin[3], Float:distance[3], greatest;
		pev(id, pev_origin, player_origin);
		distance[0] = abs_f(player_origin[0] - g_aimOrigin[2][0]);
		distance[1] = abs_f(player_origin[1] - g_aimOrigin[2][1]);
		distance[2] = abs_f(player_origin[2] - g_aimOrigin[2][2]);
		for(new i = 0; i < 3; i++)
		{
			if(distance[i] > distance[greatest]) greatest = i;
		}
		switch(flag)
		{
			case 1: {g_aimOrigin[2][greatest] += (player_origin[greatest] > g_aimOrigin[2][greatest] ? DISTANCE : -DISTANCE);}
			case 2: {g_aimOrigin[2][greatest] -= (player_origin[greatest] > g_aimOrigin[2][greatest] ? DISTANCE : -DISTANCE);}
			case 3: {g_aimOrigin[2][greatest] += (player_origin[greatest] > g_aimOrigin[2][greatest] ? 2.0 : -2.0);}
		}
		engfunc(EngFunc_SetOrigin, g_entity, g_aimOrigin[2]);
	}
	return 1;
}



//*****************************************************************************************************************
//************************************************   F U N C T I O N S  *******************************************
//*****************************************************************************************************************

//+++++ Taken from fakemeta_util.inc (very nice! many thanks to VEN from http://forums.alliedmods.net/index.php +++++
bool:is_in_viewcone(index, const Float:point[3])
{
	new Float:angles[3]
	pev(index, pev_angles, angles)
	engfunc(EngFunc_MakeVectors, angles)
	global_get(glb_v_forward, angles)
	angles[2] = 0.0

	new Float:origin[3], Float:diff[3], Float:norm[3]
	pev(index, pev_origin, origin)
	vec_sub(point, origin, diff)
	diff[2] = 0.0
	vec_normalize(diff, norm)

	new Float:dot, Float:fov
	dot = vec_dot(norm, angles)
	pev(index, pev_fov, fov)
	if (dot >= floatcos(fov * M_PI / 360))
		return true

	return false
}

get_aim_origin(index, Float:origin[3])
{
	static Float:start[3], Float:view_ofs[3];
	pev(index, pev_origin, start);
	pev(index, pev_view_ofs, view_ofs);
	vec_add(start, view_ofs, start);
	
	static Float:dest[3];
	pev(index, pev_v_angle, dest);
	engfunc(EngFunc_MakeVectors, dest);
	global_get(glb_v_forward, dest);
	vec_mul_scalar(dest, 9999.0, dest);
	vec_add(start, dest, dest);
	
	engfunc(EngFunc_TraceLine, start, dest, 0, index, 0);
	get_tr2(0, TR_vecEndPos, origin);
	
	return 1;
}

bool:is_aiming_at_sky(index)
{
	new target, temp;
	get_user_aiming(index,target,temp);
	if(engfunc(EngFunc_PointContents,target) == CONTENTS_SKY) return true;
	return false;
}

get_ent_in_aim_radius(index, Float:radius) 
{
	static Float:start[3], Float:view_ofs[3];
	static Float:dest[3], Float:origin[3], entclass[32];
	new ent = -1;
	
	pev(index, pev_origin, start)
	pev(index, pev_view_ofs, view_ofs)
	vec_add(start, view_ofs, start)
	pev(index, pev_v_angle, dest)
	engfunc(EngFunc_MakeVectors, dest)
	global_get(glb_v_forward, dest)
	vec_mul_scalar(dest, 9999.0, dest)
	vec_add(start, dest, dest)
	engfunc(EngFunc_TraceLine, start, dest, 0, index, 0)
	get_tr2(0, TR_vecEndPos, origin)
	while((ent = engfunc(EngFunc_FindEntityInSphere, ent, origin, radius)) != 0)
	{
		pev(ent, pev_classname, entclass, 32)
		if(equal(entclass, MEDKITCLASS) || equal(entclass, RECHARGECLASS)) return ent;
	}
	return 0
}

Float:ent_distance(ent1, ent2)
{
	new Float:mins1[3], Float:maxs1[3];
	new Float:mins2[3], Float:maxs2[3];
	new Float:dist[3];
	pev(ent1, pev_absmin, mins1);
	pev(ent1, pev_absmax, maxs1);
	pev(ent2, pev_absmin, mins2);
	pev(ent2, pev_absmax, maxs2);
	for (new i = 0; i < 3; ++i)
	{
		if (mins1[i] > maxs2[i]) dist[i] = mins1[i] - maxs2[i];
		else if (mins2[i] > maxs1[i]) dist[i] = mins2[i] - maxs1[i];
	}
	return vector_length(dist);
}

/*bool:is_visible(index, const Float:point[3], ignoremonsters = 0)
{
	new Float:start[3], Float:view_ofs[3];
	pev(index, pev_origin, start);
	pev(index, pev_view_ofs, view_ofs);
	vec_add(start, view_ofs, start);

	engfunc(EngFunc_TraceLine, start, point, ignoremonsters, index, 0);

	new Float:fraction;
	get_tr2(0, TR_flFraction, fraction);
	if (fraction == 1.0)
		return true;

	return false;
}*/

minimize_normal(Float:normal[3])
{
	normal[0] /= 10.0;
	normal[1] /= 10.0;
	normal[2] /= 10.0;
	return 1;
}

Float:abs_f(Float:x)
{
	if(x < 0) return (-1.0 * x);
	return x;
}

equal_f(Float:origin1[3], Float:origin2[3])
{
	new num_equal = (origin1[0] == origin2[0] ? 1 : 0);
	num_equal += (origin1[1] == origin2[1] ? 1 : 0);
	num_equal += (origin1[2] == origin2[2] ? 1 : 0);
	return num_equal;
}

Float:sum_f(Float:origin1[3], Float:origin2[3])
{
	new Float:result[3];
	result[0] = origin1[0] + origin2[0];
	result[1] = origin1[1] + origin2[1];
	result[2] = origin1[2] + origin2[2];
	return result;
}

Float:diff_f(Float:origin1[3], Float:origin2[3])
{
	new Float:result[3];
	result[0] = origin1[0] - origin2[0];
	result[1] = origin1[1] - origin2[1];
	result[2] = origin1[2] - origin2[2];
	return result;
}

Float:cross_product(Float:origin1[3], Float:origin2[3])
{
	new Float:result[3];
	result[0] = origin1[1]*origin2[2] - origin1[2]*origin2[1];
	result[1] = origin1[2]*origin2[0] - origin1[0]*origin2[2];
	result[2] = origin1[0]*origin2[1] - origin1[1]*origin2[0];
	return result;
}


//+++++ Taken from xs.inc (very nice! Many thanks to PM from http://forums.alliedmods.net/index.php +++++
vec_add(const Float:in1[], const Float:in2[], Float:out[])
{
	out[0] = in1[0] + in2[0];
	out[1] = in1[1] + in2[1];
	out[2] = in1[2] + in2[2];
}

vec_sub(const Float:in1[], const Float:in2[], Float:out[])
{
	out[0] = in1[0] - in2[0];
	out[1] = in1[1] - in2[1];
	out[2] = in1[2] - in2[2];
}

vec_mul_scalar(const Float:vec[], Float:scalar, Float:out[])
{
	out[0] = vec[0] * scalar;
	out[1] = vec[1] * scalar;
	out[2] = vec[2] * scalar;
}

vec_normalize(const Float:vec[], Float:out[])
{
	new Float:invlen = xs_rsqrt(vec[0]*vec[0] + vec[1]*vec[1] + vec[2]*vec[2]);
	out[0] = vec[0] * invlen;
	out[1] = vec[1] * invlen;
	out[2] = vec[2] * invlen;
}

Float:xs_rsqrt(Float:x)
{
	return 1.0 / floatsqroot(x);
}
	
Float:vec_dot(const Float:vec1[], const Float:vec2[])
{
	return vec1[0]*vec2[0] + vec1[1]*vec2[1] + vec1[2]*vec2[2];
}

get_station_num(id)
{
	for(new m = 0; m < g_medkit_count; m++)
		if(g_medkit_id[m] == id) return m;

	for(new r = 0; r < g_recharge_count; r++)
		if(g_recharge_id[r] == id) return r;

	return -1;
}

//+++++ Manipulate the user armor ++++++
set_realarmor(id, armor=2)
{
	if(is_module_loaded("cstrike") != -1)
	{
		set_pdata_int(id, OFFSET_ARMORTYPE, armor, OFFSET_LINUX);
		message_begin(MSG_ONE, g_umsgA, {0,0,0}, id);
		write_byte(1);
		message_end();
	}
}


Аватар
OciXCrom
Извън линия
Администратор
Администратор
Мнения: 7206
Регистриран на: 06 Окт 2016, 19:20
Местоположение: /resetscore
Се отблагодари: 117 пъти
Получена благодарност: 1295 пъти
Обратна връзка:

Health Armor Stations плъгина да не ти прави 100 кръвта, когато имаш над 100 и използваш станция

Мнение от OciXCrom » 22 Окт 2017, 20:47

Код за потвърждение: Избери целия код

/**********************************************************************************
* 									Health/Armor-Stations
*
*
* Author: regalis ([email protected])
*
*
*	Version: 0.3.5
*
*
*
*	Description:
*		Do you know HalfLife Deathmatch?
*		There are Stations to recharge your Health and you Armor.
*		Now you can have these Station in Counterstrike too!
*		Place the Stations you want where you want ;)
*
*		To place a Station make sure you are an admin and bind a key to "+place_station".
*		Now press the key and aim at where you want to place the station, release the key to choose which sort of station you want to place.
*		With the commands "push_station" and "pull_station" you can pull or push the station in the direction you are looking.
*		If you have choosen the station which fits your needs you can save it to the config-file which is automaticaly created for each map.
*		That all...
*		To use these Stations just stand near it and press your USE-key (standard: E)
*		The reloading of the Station is triggered as soon as the Station gets empty!
*
*
*
*
*	Admin-Commands:
*		"+place_station" - Place an Health/Armor-Station on the wall in front of you
*		"push_station" - Move the Health/Armor-Station away of you
*		"pull_station" - Move the Health/Armor-Station closer to you
*		"del_station" - Delete the Healt/Armor-Station at which you aim
*
*
*
* CVARS:
*		HA_maxhealth - How much health is in a HealthStation for everyone [number of HP](0-100) (Default: 40 HP)
*		HA_maxplayerhealth - Set the maximum amount of health a player can charge [100 - 255] (Default: 255 HP)
*		HA_healthpersec - Set the amount of HP a player get per chargecycle [1 - ?] (Default: 4 HP should be 8-12 HP per second) 
*		HA_maxarmor - How much armor is in a ArmorStation for everyone [number of AP]	(0-100)	(Default: 40 AP)
*		HA_maxplayerarmor - Set the maximum amount of armor a player can charge [100 - 255] (Default: 255 AP)
*		HA_armorpersec - Set the amount of AP a player get per chargecycle [1 - ?] (Default: 4 AP should be 8-12 AP per second)
*		HA_healthreloadtime - How long the player have to wait till he can use the same HealthStation again [number in seconds](Default: 30 sec)
*		HA_armorreloadtime - How long the player have to wait till he can use the same ArmorStation again [number in seconds]	(Default: 30 sec)
*		HA_gloweffect - Let the HealthStations glow red and the ArmorStations glow blue [0|1]	(on|off) (Default: 1)
*		
*
*
*	Requirements:
*		Fakemeta-Modul
*
*
*
*	Changelog:
*		v0.1:
*			@ initial release
*
*		v0.2:
*			! Fixed a sound bug
*			+ Added support for newly placed station giving HP/AP
*			+ Added 4 new CVARS for more customization
*
*		v0.3:
*			- Removed static declaration for global Variables
*			- Removed "stock" for functions
*			+ Added a function to delete placed stations
*			+ Added real armor to the stations (only for Counterstrike)
*		
*		v0.3.1:
*			! fixed a bug with realarmor(it is only for CounterStrike)
*
*		v0.3.5:
*			!fixed a bug when you placed a station at the sky/ceiling the server crashed...now it is handled
*
*
* Known Bugs:
*		- At some placing angles the station looks black
*			(Workaround: Just place it from another angle)
*
*
*	TODO:
*		- maybe optimizing a little
*
*
*	Credits:
*		stupok69 for his nice In-Game-Ads where i have taken the Station placing (http://forums.alliedmods.net/showthread.php?p=424583)
*		Cheap_suit for his help here: (http://forums.alliedmods.net/showpost.php?p=482976&postcount=4)
*		Alka for the help on fixing the bug with the "placing at the sky/ceiling"
*		Simon Logic for his idea with Armour-Absence-Fix Plugin here: (http://forums.alliedmods.net/showthread.php?t=55591)
*		VEN for his fakemeta_util.inc here: (http://forums.alliedmods.net/showthread.php?t=28284)
*		PM for his xs.inc
*
*
***********************************************************************************/
#include <amxmodx>
#include <amxmisc>
#include <fakemeta>


//++++++++++++++++++++
//+++++ DEFINES ++++++
//++++++++++++++++++++
// Define the offset for the Armor manipulation stock
#if cellbits == 32
	#define OFFSET_ARMORTYPE 112
#else
	#define OFFSET_ARMORTYPE 137
#endif
#define OFFSET_LINUX 5

#define CONFIGFOLDER "HA-Stations"
#define PLACESTEPFREQUENCY 10
#define DISTANCE 3.0
#define ADMIN_ACCESS_LEVEL ADMIN_BAN
#define MAXPLAYERS 32
#define MAXMEDKITS 15
#define MAXRECHARGES 15
#define MEDKITCLASS "ha_medkit"
#define RECHARGECLASS "ha_recharge"
#define SND_STOP (1<<5)

// Define the Author :P 
#define PLUGIN "Healt&Armor-Stations"
#define VERSION "0.3.5"
#define AUTHOR "regalis"


//+++++++++++++++++++++++++++++
//+++++ GLOBAL VARIABLES ++++++
//+++++++++++++++++++++++++++++
// The models
new const g_models[][] =
{
	"models/stz/HealthArmor-Stations/HealthStation.mdl",
	"models/stz/HealthArmor-Stations/ArmorStation.mdl"
}
new const gModelIndex = sizeof g_models;

// The Glow colors
new const Float:g_colors[][3] = {
	{255.0, 0.0, 0.0},
	{0.0, 0.0, 255.0}
}

// ################## FOR FUTURE USAGE #################
//new static bool:g_restart_attempt[33];
// ################## FOR FUTURE USAGE #################


//+++++ MESSAGE IDs ++++++
new g_umsgA;
//new g_msgM;
	
	
//+++++ Adminstuff + Filehandling +++++
new g_prethink_placestepper;
new g_curmodeltype;
new g_entity;
new g_curAdjuster = -1;
new Float:g_aimOrigin[3][3];
new Float:g_entity_angles[3];
new g_file_name[256]
new g_map_name[32];
new bool:g_adjusting = false;

//+++++ Deleting +++++
new g_del_num;
new g_del_models[MAXMEDKITS+MAXRECHARGES];
new Float:g_del_origins[MAXMEDKITS+MAXRECHARGES][3];
new Float:g_del_angles[MAXMEDKITS+MAXRECHARGES][3];

//+++++ Checking the usage +++++
new Float:g_nextstep[MAXPLAYERS+1];
new Float:g_chargesteppfrequency = 0.5;
new bool:g_faraway;
new g_cvar_gloweffect;

// Medkit
new Float:g_medkit_coords[MAXMEDKITS][3];
new Float:g_medkit_angles[MAXMEDKITS][3];
new g_medkit_id[MAXMEDKITS];
new g_medkit_count;

// Recharge
new Float:g_recharge_coords[MAXRECHARGES][3];
new Float:g_recharge_angles[MAXRECHARGES][3];
new g_recharge_id[MAXRECHARGES];
new g_recharge_count;


//+++++ Healthhandling +++++
new g_medkit_value[MAXMEDKITS][MAXPLAYERS+1];
new bool:g_snd_medkit[MAXMEDKITS][MAXPLAYERS+1];
new g_cvar_maxhealth;
new g_cvar_maxplayerhealth;
new g_cvar_healthpersec
new Float:g_cvar_medkitreloadtime;
new g_pHealth[MAXPLAYERS+1];


//+++++ Armorhandling +++++
new g_recharge_value[MAXRECHARGES][MAXPLAYERS+1];
new bool:g_snd_recharge[MAXRECHARGES][MAXPLAYERS+1];
new g_cvar_maxarmor;
new g_cvar_maxplayerarmor;
new g_cvar_armorpersec;
new Float:g_cvar_rechargereloadtime;
new g_pArmor[MAXPLAYERS+1];


//+++++ GLOBAL CVAR POINTER ++++++
new gcvar_maxhealth;
new gcvar_maxplayerhealth;
new gcvar_medkitreloadtime;
new gcvar_healthpersec
new gcvar_maxarmor;
new gcvar_maxplayerarmor;
new gcvar_rechargereloadtime;
new gcvar_armorpersec;
new gcvar_gloweffect;



//++++++++++++++++++++++++
//+++++ PLUGIN-INIT ++++++
//++++++++++++++++++++++++
public plugin_init()
{
	register_plugin(PLUGIN, VERSION, AUTHOR);
	register_cvar(PLUGIN, VERSION, FCVAR_SERVER);
	
	//+++++ cvar pointer ++++++
	gcvar_maxhealth = register_cvar("HA_maxhealth", "40");
	gcvar_maxplayerhealth = register_cvar("HA_maxplayerhealth", "100");
	gcvar_healthpersec = register_cvar("HA_healthpersec", "2")
	gcvar_maxarmor = register_cvar("HA_maxarmor", "40");
	gcvar_maxplayerarmor = register_cvar("HA_maxplayerarmor", "100");
	gcvar_armorpersec = register_cvar("HA_armorpersec", "2");
	gcvar_medkitreloadtime = register_cvar("HA_healthreloadtime", "20");
	gcvar_rechargereloadtime = register_cvar("HA_armorreloadtime", "20");
	gcvar_gloweffect = register_cvar("HA_gloweffect", "1");
	
	//+++++ Admin Commands +++++
	register_clcmd("+place_station", "cmd_place_station", ADMIN_ACCESS_LEVEL);
	register_clcmd("-place_station", "cmd_place_station", ADMIN_ACCESS_LEVEL);
	register_clcmd("pull_station", "pull_station", ADMIN_ACCESS_LEVEL);
	register_clcmd("push_station", "push_station", ADMIN_ACCESS_LEVEL);
	register_clcmd("del_station", "del_station", ADMIN_ACCESS_LEVEL);
	
	//+++++ Menu Commands +++++
	register_menucmd(register_menuid("save_menu"), (1<<0)|(1<<1), "action_save");
	register_menucmd(register_menuid("select_menu"), 1023, "action_select");
	
	//################## FOR FUTURE USAGE #################
	/*
	//+++++ Client Commands ++++++
	register_clcmd("fullupdate", "clcmd_fullupdate");
	//+++++ Events ++++++
	register_event("ResetHUD", "event_hud_reset", "be");
	register_event("TextMsg", "event_restart_attempt", "a", "2=#Game_will_restart_in");
	*/
	//################## FOR FUTURE USAGE #################
	
	//+++++ Message ID +++++
	g_umsgA = get_user_msgid("ArmorType");
	//g_umsgM = get_user_msgid("Money");
	
	//+++++ Logevents ++++++
	register_logevent("event_roundStart", 2, "1=Round_Start");
	register_logevent("event_round_end", 2, "1=Round_End");
	
	//+++++ Forwards +++++
	register_forward(FM_PlayerPreThink, "PreThink");
	
	//+++++ Read the Config +++++
	readCvars();
	
	//+++++ Load the saved Stations +++++
	load_saved_stations(g_file_name);
}



//++++++++++++++++++++++++++++
//+++++ PLUGIN-PRECACHE ++++++
//++++++++++++++++++++++++++++
public plugin_precache()
{
	new configs_dir[64];
	get_configsdir(configs_dir, 63);
	get_mapname(g_map_name, 31);
	
	// Save the Configfilename in a global variable
	formatex(g_file_name, 255, "%s/%s", configs_dir, CONFIGFOLDER);
	if(!dir_exists(g_file_name)) mkdir(g_file_name);
	formatex(g_file_name, 255, "%s/%s/%s.txt", configs_dir, CONFIGFOLDER, g_map_name);
	
	// Precache the models
	for(new m = 0; m < gModelIndex; m++) engfunc(EngFunc_PrecacheModel,g_models[m]);
	
	
	// Precache the sounds
	precache_sound("stz/HealthArmor-Stations/ArmorRecharge.wav");
	precache_sound("stz/HealthArmor-Stations/ArmorRechargeOk.wav");
	precache_sound("stz/HealthArmor-Stations/ArmorRechargeNo.wav");
	precache_sound("stz/HealthArmor-Stations/HealthRecharge.wav");
	precache_sound("stz/HealthArmor-Stations/HealthRechargeOk.wav");
	precache_sound("stz/HealthArmor-Stations/HealthRechargeNo.wav");
}




//*****************************************************************************************************************
//****************************************   G E N E R A L S T U F F   ********************************************
//*****************************************************************************************************************

//################## FOR FUTURE USAGE #################
/* 
//+++++ CLIENT COMMAND FULLUPDATE ++++++
public clcmd_fullupdate()
{
	return PLUGIN_HANDLED_MAIN;
}

//+++++ Event RESTART-ATTEMPT ++++++
public event_restart_attempt()
{
	new players[32], num;
	get_players(players, num, "a");
	for (new i; i < num; ++i)
	{
		g_restart_attempt[players[i]] = true;
	}
}

//+++++ Event HUD-RESET ++++++
public event_hud_reset(id)
{
	if (g_restart_attempt[id])
	{
		g_restart_attempt[id] = false;
		return;
	}
	event_player_spawn(id);
}

//+++++ Event PLAYERSPAWN ++++++
public event_player_spawn(id)
{
	// nothing to do...maybe later ;)
}
*/
//################## FOR FUTURE USAGE #################

//+++++ Event ROUNDSTART ++++++
public event_roundStart()
{
	readCvars();
	resetStations();
}

public event_round_end()
{
	resetStations();
}

//+++++ READ THE CVARS +++++++
readCvars()
{
	// Putting the CVARS in the global variables
	g_cvar_maxarmor = get_pcvar_num(gcvar_maxarmor);
	g_cvar_maxplayerarmor = get_pcvar_num(gcvar_maxplayerarmor);
	g_cvar_armorpersec = get_pcvar_num(gcvar_armorpersec);
	g_cvar_maxhealth = get_pcvar_num(gcvar_maxhealth);
	g_cvar_maxplayerhealth = get_pcvar_num(gcvar_maxplayerhealth);
	g_cvar_healthpersec = get_pcvar_num(gcvar_healthpersec);
	g_cvar_rechargereloadtime = get_pcvar_float(gcvar_rechargereloadtime);
	g_cvar_medkitreloadtime = get_pcvar_float(gcvar_medkitreloadtime);
	g_cvar_gloweffect = get_pcvar_num(gcvar_gloweffect);
}



//*****************************************************************************************************************
//*****************************************   S T A T I O N H A N D L I N G   *************************************
//*****************************************************************************************************************

//+++++ RESET THE STATIONS +++++++
resetStations()
{
	for (new i=0; i < 32; i++)
	{
		// Reset medkit-Stations to the cvar value
		for(new m = 0; m < g_medkit_count; m++)
		{
			if(task_exists(434774+i+m))	 remove_task(434774+i+m);
			g_medkit_value[m][i] = g_cvar_maxhealth;
			if(g_snd_medkit[m][i])
			{
				emit_sound(g_medkit_id[m], CHAN_WEAPON, "stz/HealthArmor-Stations/HealthRecharge.wav", 1.0, ATTN_NORM, SND_STOP, PITCH_NORM);
				g_snd_medkit[m][i] = false;
			}
		}
		
		// Reset recharge-Stations to the cvar value
		for(new r = 0; r < g_recharge_count; r++)
		{
			if(task_exists(477434+i+r))	 remove_task(477434+i+r);
			g_recharge_value[r][i] = g_cvar_maxarmor;
			if(g_snd_recharge[r][i])
			{
				emit_sound(g_recharge_id[r], CHAN_WEAPON, "stz/HealthArmor-Stations/ArmorRecharge.wav", 1.0, ATTN_NORM, SND_STOP, PITCH_NORM);
				g_snd_recharge[r][i] = false;
			}
		}
	}
}


//+++++ RESET A HEALTH STATION +++++
public reset_HealthStation(param[2])
{
	// Get the params
	new id = param[0];
	new number = param[1];
	
	// Reset the value of the certain Station to the value stored in the cvar
	g_medkit_value[number][id] = g_cvar_maxhealth;
}


//+++++ RESET A ARMOR STATION +++++
public reset_ArmorStation(param[2])
{
	// Get the params
	new id = param[0];
	new number = param[1];
	
	// Reset the value of the certain Station to the value stored in the cvar
	g_recharge_value[number][id] = g_cvar_maxarmor;
}


remove_stations()
{
	new ent = -1;
	while((ent = engfunc(EngFunc_FindEntityByString, -1, "classname", MEDKITCLASS)) != 0)
	{
		if(pev_valid(ent))
		{
			engfunc(EngFunc_RemoveEntity, ent);
		}
	}
	ent = -1;
	while((ent = engfunc(EngFunc_FindEntityByString, -1, "classname", RECHARGECLASS)) != 0)
	{
		if(pev_valid(ent))
		{
			engfunc(EngFunc_RemoveEntity, ent);
		}
	}
	g_del_num = 0;
	g_medkit_count = 0;
	g_recharge_count = 0;
}


//*****************************************************************************************************************
//********************************   H E A L T H - A R M O R H A N D L I N G  *************************************
//*****************************************************************************************************************

//+++++ Give the player health +++++
GiveHealth(id, number)
{
	if(g_medkit_value[number][id] > 0)
	{
		// The HealthValue in the current station for this player is more than 0
		g_pHealth[id] = pev(id, pev_health); // Get the player health
		if(g_pHealth[id] <= g_cvar_maxplayerhealth-g_cvar_healthpersec)
		{
			g_medkit_value[number][id] -= g_cvar_healthpersec; // subtract the given Healthvalue from the Health-Station value
			set_pev(id, pev_health, float(g_pHealth[id]+g_cvar_healthpersec)); // Give the player the Health
			if(!g_snd_medkit[number][id])
			{
				emit_sound(g_medkit_id[number], CHAN_WEAPON, "stz/HealthArmor-Stations/HealthRecharge.wav", 1.0, ATTN_NORM, 0, PITCH_NORM);
			}
		}
		else
		{
			if(g_pHealth[id] == g_cvar_maxplayerhealth)
			{
				emit_sound(g_medkit_id[number], CHAN_WEAPON, "stz/HealthArmor-Stations/HealthRecharge.wav", 1.0, ATTN_NORM, SND_STOP, PITCH_NORM);
				emit_sound(g_medkit_id[number], CHAN_STREAM, "stz/HealthArmor-Stations/HealthRechargeNo.wav", 1.0, ATTN_NORM, 0, PITCH_NORM);
			}
			else
			{
				set_pev(id, pev_health, float(g_cvar_maxplayerhealth));
				emit_sound(g_medkit_id[number], CHAN_WEAPON, "stz/HealthArmor-Stations/HealthRecharge.wav", 1.0, ATTN_NORM, SND_STOP, PITCH_NORM);
				emit_sound(id, CHAN_STREAM, "stz/HealthArmor-Stations/HealthRechargeOk.wav", 1.0, ATTN_NORM, 0, PITCH_NORM);
			}
		}
	}
	else
	{
		emit_sound(g_medkit_id[number], CHAN_WEAPON, "stz/HealthArmor-Stations/HealthRecharge.wav", 1.0, ATTN_NORM, SND_STOP, PITCH_NORM);
		emit_sound(g_medkit_id[number], CHAN_STREAM, "stz/HealthArmor-Stations/HealthRechargeNo.wav", 1.0, ATTN_NORM, 0, PITCH_NORM);
		// Health-Station is empty
		if(!task_exists(434774+id+number))
		{
			new param[2];
			param[0] = id;
			param[1] = number;
			// Plan a task to refresh the Health-Station value
			set_task(g_cvar_medkitreloadtime, "reset_HealthStation", 434774+id+number, param, 2);
		}
	}
}

//+++++ Give the player armor +++++
GiveArmor(id, number)
{
	if(g_recharge_value[number][id] > 0)
	{
		// The ArmorValue in the current station for this player is more than 0
		g_pArmor[id] = pev(id, pev_armorvalue); // Get the player armor
		if(g_pArmor[id] <= g_cvar_maxplayerarmor-g_cvar_armorpersec)
		{
			// Player have a lower ArmorValue than 100
			g_recharge_value[number][id] -= g_cvar_armorpersec;	// Subtract the given armor from the Armor-Station value
			if(!get_pdata_int(id, OFFSET_ARMORTYPE, OFFSET_LINUX)) set_realarmor(id);
			set_pev(id, pev_armorvalue, float(g_pArmor[id]+g_cvar_armorpersec)); // Give the player the Armor
			
			if(!g_snd_recharge[number][id])
			{
				emit_sound(g_recharge_id[number], CHAN_WEAPON, "stz/HealthArmor-Stations/ArmorRecharge.wav", 1.0, ATTN_NORM, 0, PITCH_NORM);
			}
		}
		else
		{
			if(g_pArmor[id] == g_cvar_maxplayerarmor)
			{
				emit_sound(g_recharge_id[number], CHAN_WEAPON, "stz/HealthArmor-Stations/ArmorRecharge.wav", 1.0, ATTN_NORM, SND_STOP, PITCH_NORM);
				emit_sound(g_recharge_id[number], CHAN_STREAM, "stz/HealthArmor-Stations/ArmorRechargeNo.wav", 1.0, ATTN_NORM, 0, PITCH_NORM);
			}
			else
			{
				set_pev(id, pev_armorvalue, float(g_cvar_maxplayerarmor)); // If player have between 96-100 Armor set it to 100
				emit_sound(g_recharge_id[number], CHAN_WEAPON, "stz/HealthArmor-Stations/ArmorRecharge.wav", 1.0, ATTN_NORM, SND_STOP, PITCH_NORM);
				emit_sound(id, CHAN_STREAM, "stz/HealthArmor-Stations/ArmorRechargeOk.wav", 1.0, ATTN_NORM, 0, PITCH_NORM);
			}
		}
	}
	else
	{
		emit_sound(g_recharge_id[number], CHAN_WEAPON, "stz/HealthArmor-Stations/ArmorRecharge.wav", 1.0, ATTN_NORM, SND_STOP, PITCH_NORM);
		emit_sound(g_recharge_id[number], CHAN_STREAM, "stz/HealthArmor-Stations/ArmorRechargeNo.wav", 1.0, ATTN_NORM, 0, PITCH_NORM);
		// Armor-Station is empty
		if(!task_exists(477434+id+number))
		{
			new param[2];
			param[0] = id;
			param[1] = number;
			// Plan a task to refresh the Armor-Station value
			set_task(g_cvar_rechargereloadtime, "reset_ArmorStation", 477434+id+number, param, 2);
		}
	}
}


//*****************************************************************************************************************
//*****************************************   F I L E H A N D L I N G   *******************************************
//*****************************************************************************************************************

//+++++ SAVE POSITION TO FILE ++++++
public save_pos()
{
	new text[256];
	
	get_configsdir(g_file_name, 255);
	format(g_file_name, 255, "%s/%s/%s.txt", g_file_name, CONFIGFOLDER, g_map_name);
	
	pev(g_entity, pev_angles, g_entity_angles);
	formatex(text, 255, "^n%s^norigin %f %f %f^nangles %f %f %f", g_models[g_curmodeltype], g_aimOrigin[2][0], g_aimOrigin[2][1], g_aimOrigin[2][2], g_entity_angles[0], g_entity_angles[1], g_entity_angles[2]);
	write_file(g_file_name, text);
	
	if(g_curmodeltype == 0)
	{
		g_medkit_coords[g_medkit_count][0] = g_aimOrigin[2][0];
		g_medkit_coords[g_medkit_count][1] = g_aimOrigin[2][1];
		g_medkit_coords[g_medkit_count][2] = g_aimOrigin[2][2];
		g_medkit_angles[g_medkit_count][0] = g_entity_angles[0];
		g_medkit_angles[g_medkit_count][1] = g_entity_angles[1];
		g_medkit_angles[g_medkit_count][2] = g_entity_angles[2];
		g_medkit_id[g_medkit_count] = g_entity;
		g_medkit_count++;
	}
	else
	{
		g_recharge_coords[g_recharge_count][0] = g_aimOrigin[2][0];
		g_recharge_coords[g_recharge_count][1] = g_aimOrigin[2][1];
		g_recharge_coords[g_recharge_count][2] = g_aimOrigin[2][2];
		g_recharge_angles[g_recharge_count][0] = g_entity_angles[0];
		g_recharge_angles[g_recharge_count][1] = g_entity_angles[1];
		g_recharge_angles[g_recharge_count][2] = g_entity_angles[2];
		g_recharge_id[g_recharge_count] = g_entity;
		g_recharge_count++;
	}	
	g_entity = 0;
	resetStations();
}

//+++++ LOAD THE SAVED Stations ++++++
load_saved_stations(file_name[])
{
	new lastread = 0;
	new file_handle = fopen(file_name, "r");
	
	if(!file_handle) return PLUGIN_HANDLED;
		
	new file_text[64];
	new ent, str_value[3][16];
	
	while(!feof(file_handle))
	{
		fgets(file_handle, file_text, 63);
		trim(file_text);
		
		if(equal(file_text, "//", 2) || !file_text[0]) continue;
		
		if(contain(file_text, "HealthStation.mdl") != -1)
		{
			if(!file_exists(file_text))
			{
				log_amx("Error: Failed to load HealthStation.mdl, model does not exist.", file_text);
				continue;
			}
			ent = engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, "info_target"));
			engfunc(EngFunc_SetModel, ent, file_text);
			set_pev(ent, pev_classname, MEDKITCLASS);
			set_pev(ent, pev_controller_0, 125);
			set_pev(ent, pev_controller_1, 125);
			set_pev(ent, pev_controller_2, 125);
			set_pev(ent, pev_controller_3, 125);
			set_pev(ent, pev_solid, 2);
			
			setGlow(ent);
			g_medkit_id[g_medkit_count] = ent;
			lastread = 1;
		}
		else if(contain(file_text, "ArmorStation.mdl") != -1)
		{
			if(!file_exists(file_text))
			{
				log_amx("Error: Failed to load ArmorStation.mdl, model does not exist.");
				continue;
			}
			ent = engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, "info_target"));
			engfunc(EngFunc_SetModel, ent, file_text);
			set_pev(ent, pev_classname, RECHARGECLASS);
			set_pev(ent, pev_controller_0, 125);
			set_pev(ent, pev_controller_1, 125);
			set_pev(ent, pev_controller_2, 125);
			set_pev(ent, pev_controller_3, 125);
			set_pev(ent, pev_solid, 2);
			
			setGlow(ent);
			g_recharge_id[g_recharge_count] = ent;
			lastread = 2;
		}
		else if(equal(file_text, "origin", 6))
		{
			parse(file_text[6], str_value[0], 15, str_value[1], 15, str_value[2], 15);
			
			switch(lastread)
			{
				case 1:
				{
					g_medkit_coords[g_medkit_count][0] = str_to_float(str_value[0]);
					g_medkit_coords[g_medkit_count][1] = str_to_float(str_value[1]);
					g_medkit_coords[g_medkit_count][2] = str_to_float(str_value[2]);
					engfunc(EngFunc_SetOrigin, ent, g_medkit_coords[g_medkit_count]);
				}
				case 2:
				{
					g_recharge_coords[g_recharge_count][0] = str_to_float(str_value[0]);
					g_recharge_coords[g_recharge_count][1] = str_to_float(str_value[1]);
					g_recharge_coords[g_recharge_count][2] = str_to_float(str_value[2]);
					engfunc(EngFunc_SetOrigin, ent, g_recharge_coords[g_recharge_count]);					
				}
			}		
		}
		else if(equal(file_text, "angles", 6))
		{
			parse(file_text[6], str_value[0], 15, str_value[1], 15, str_value[2], 15);
			
			switch(lastread)
			{
				case 1:
				{
					g_medkit_angles[g_medkit_count][0] = str_to_float(str_value[0]);
					g_medkit_angles[g_medkit_count][1] = str_to_float(str_value[1]);
					g_medkit_angles[g_medkit_count][2] = str_to_float(str_value[2]);
					set_pev(ent, pev_angles, g_medkit_angles[g_medkit_count]);
					
					new Float:mins[3] = {-2.0, -2.0, 38.0};
					new Float:maxs[3] = {2.0, 2.0, 42.0};
					engfunc(EngFunc_SetSize, ent, mins, maxs);
					g_medkit_count++;
				}
				case 2:
				{
					g_recharge_angles[g_recharge_count][0] = str_to_float(str_value[0]);
					g_recharge_angles[g_recharge_count][1] = str_to_float(str_value[1]);
					g_recharge_angles[g_recharge_count][2] = str_to_float(str_value[2]);
					set_pev(ent, pev_angles, g_recharge_angles[g_recharge_count]);
					
					new Float:mins[3] = {-2.0, -2.0, 38.0};
					new Float:maxs[3] = {2.0, 2.0, 42.0};
					engfunc(EngFunc_SetSize, ent, mins, maxs);
					g_recharge_count++;
				}
			}	
			lastread = 0;
		}
	}
	fclose(file_handle);
	resetStations();
	return PLUGIN_HANDLED;
}



delete_saved_stations(num, del_class)
{
	get_configsdir(g_file_name, 255);
	format(g_file_name, 255, "%s/%s/%s.txt", g_file_name, CONFIGFOLDER, g_map_name);
	new file_handle = fopen(g_file_name, "r");
	if(!file_handle) return PLUGIN_HANDLED;
	
	new del_medkit_num;
	new del_recharge_num;
	new file_text[64];
	new str_value[3][16];
	
	while(!feof(file_handle))
	{
		fgets(file_handle, file_text, 63);
		trim(file_text);
		
		if(equal(file_text, "//", 2) || !file_text[0]) continue;
		
		if(contain(file_text, "HealthStation.mdl") != -1)
		{
			if(del_medkit_num != num)
			{
				g_del_models[g_del_num] = 0;
				del_medkit_num++;
			}
			else if(del_class == 1)
			{
				fgets(file_handle, file_text, 63);
				fgets(file_handle, file_text, 63);
				del_medkit_num++;
			}
			else
			{
				g_del_models[g_del_num] = 0;
				del_medkit_num++;
			}
		}
		
		else if(contain(file_text, "ArmorStation.mdl") != -1)
		{
			if(del_recharge_num != num)
			{
				g_del_models[g_del_num] = 1;
				del_recharge_num++;
			}
			else if(del_class == 2)
			{
				fgets(file_handle, file_text, 63);
				fgets(file_handle, file_text, 63);
				del_recharge_num++;
			}
			else
			{
				g_del_models[g_del_num] = 1;
				del_recharge_num++;
			}
		}
		
		else if(equal(file_text, "origin", 6))
		{
			parse(file_text[6], str_value[0], 15, str_value[1], 15, str_value[2], 15);
			g_del_origins[g_del_num][0] = str_to_float(str_value[0]);
			g_del_origins[g_del_num][1] = str_to_float(str_value[1]);
			g_del_origins[g_del_num][2] = str_to_float(str_value[2]);
		}
		
		else if(equal(file_text, "angles", 6))
		{
			parse(file_text[6], str_value[0], 15, str_value[1], 15, str_value[2], 15);
			g_del_angles[g_del_num][0] = str_to_float(str_value[0]);
			g_del_angles[g_del_num][1] = str_to_float(str_value[1]);
			g_del_angles[g_del_num][2] = str_to_float(str_value[2]);
			g_del_num++;
		}
	}
	
	fclose(file_handle);
	save_stations_again();
	
	return PLUGIN_HANDLED;
}


public save_stations_again()
{
	new text[256];	
	get_configsdir(g_file_name, 255);
	format(g_file_name, 255, "%s/%s/%s.txt", g_file_name, CONFIGFOLDER, g_map_name);
	new tmpfile = fopen(g_file_name,"w");
	
	for(new i = 0; i < g_del_num; ++i)
	{
		formatex(text, 255, "^n%s^norigin %f %f %f^nangles %f %f %f^n", g_models[g_del_models[i]], g_del_origins[i][0], g_del_origins[i][1], g_del_origins[i][2], g_del_angles[i][0], g_del_angles[i][1], g_del_angles[i][2]);
		fputs(tmpfile,text);
	}
	
	fclose(tmpfile);
	resetStations();
	remove_stations();
	load_saved_stations(g_file_name);
}



//*****************************************************************************************************************
//*********************************************   P R E T H I N K  ************************************************
//*****************************************************************************************************************

public PreThink(id)
{
	//+++++ PLACING STUFF (ADMIN) +++++
	if(g_adjusting && id == g_curAdjuster)
	{
		if(g_prethink_placestepper++ > PLACESTEPFREQUENCY)
		{
			if(!is_aiming_at_sky(id))
			{
				get_aim_origin(id, g_aimOrigin[2]);
	
				if(equal_f(g_aimOrigin[1], g_aimOrigin[2]) < 3)
				{
					if(pev_valid(g_entity))
					{
						engfunc(EngFunc_SetOrigin, g_entity, g_aimOrigin[2]);
						move_station(id, 3);
						
						static Float:normal[3], Float:player_origin[3], Float:test_origin[3];
						
						normal = cross_product(diff_f(g_aimOrigin[0], g_aimOrigin[1]), diff_f(g_aimOrigin[2], g_aimOrigin[1]));
						vector_to_angle(normal, g_entity_angles);
						
						minimize_normal(normal);
						test_origin = sum_f(g_aimOrigin[2], normal);
						pev(id, pev_origin, player_origin);
						
						if(get_distance_f(player_origin, test_origin) > get_distance_f(player_origin, g_aimOrigin[2]))
						{
							set_pev(g_entity, pev_angles, g_entity_angles);
						}
					}	
				}
				if(equal_f(g_aimOrigin[1], g_aimOrigin[2]) < 2 && get_distance_f(g_aimOrigin[2], g_aimOrigin[1]) > 5.0)
				{
					g_aimOrigin[0] = g_aimOrigin[1];
					g_aimOrigin[1] = g_aimOrigin[2];
				}
				g_prethink_placestepper = 0;
			}
		}
	}
	//+++++###+++++ CHECKING STUFF (STATIONS) +++++###+++++
	new Float:gametime = get_gametime();
	if(g_nextstep[id] < gametime)		// is it time for the next check?
	{		
		//~~ Check medkit-Stationstatus ~~
		for(new m = 0; m < g_medkit_count; m++)
		{
			if(pev_valid(g_medkit_id[m]))
			{
				if(ent_distance(id, g_medkit_id[m]) < 30)
				{
					// Player is near a Health-Station
					g_faraway = false;
					if(is_in_viewcone(id, g_medkit_coords[m]))
					{
						// Player is looking at a Health-Station
						if(pev(id, pev_button) & IN_USE && pev(id, pev_health) < 100.0)
						{
							// Player is pressing USE-button near a Health-Station
							GiveHealth(id, m);
							g_snd_medkit[m][id] = true;
						}
						else if(g_snd_medkit[m][id] == true)
						{
							emit_sound(g_medkit_id[m], CHAN_WEAPON, "stz/HealthArmor-Stations/HealthRecharge.wav", 1.0, ATTN_NORM, SND_STOP, PITCH_NORM);
							g_snd_medkit[m][id] = false;
						}
					}
					else if(g_snd_medkit[m][id] == true)
					{
						emit_sound(g_medkit_id[m], CHAN_WEAPON, "stz/HealthArmor-Stations/HealthRecharge.wav", 1.0, ATTN_NORM, SND_STOP, PITCH_NORM);
						g_snd_medkit[m][id] = false;
					}
				}
				else
				{
					if(ent_distance(id, g_medkit_id[m]) > 100 && g_faraway)
					{
						g_faraway = true;
						g_snd_medkit[m][id] = false;
					}
					if(g_snd_medkit[m][id] == true) emit_sound(g_medkit_id[m], CHAN_WEAPON, "stz/HealthArmor-Stations/HealthRecharge.wav", 1.0, ATTN_NORM, SND_STOP, PITCH_NORM);
				}
			}
			else
			{
				log_amx("Error: Failure in map config! Please make a new one. (Health-Station nr: %d failed to load)",m);
			}
		}
		//~~ Check recharge-Stationstatus ~~
		for(new r = 0; r < g_recharge_count; r++)
		{
			if(pev_valid(g_recharge_id[r]))
			{
				if(ent_distance(id, g_recharge_id[r]) < 30)
				{
					// Player is near a Recharge-Station
					g_faraway = false;
					if(is_in_viewcone(id, g_recharge_coords[r]))
					{
						// Player is looking at a Recharge-Station
						if(pev(id, pev_button) & IN_USE)
						{
							// Player is pressing USE-Button near a Recharge-Station
							GiveArmor(id, r);
							g_snd_recharge[r][id] = true;							
						}
						else if(g_snd_recharge[r][id] == true)
						{
							emit_sound(g_recharge_id[r], CHAN_WEAPON, "stz/HealthArmor-Stations/ArmorRecharge.wav", 1.0, ATTN_NORM, SND_STOP, PITCH_NORM);
							g_snd_recharge[r][id] = false;
						}
					}
					else if(g_snd_recharge[r][id] == true)
					{
						emit_sound(g_recharge_id[r], CHAN_WEAPON, "stz/HealthArmor-Stations/ArmorRecharge.wav", 1.0, ATTN_NORM, SND_STOP, PITCH_NORM);
						g_snd_recharge[r][id] = false;
					}
				}
				else
				{
					if(ent_distance(id, g_recharge_id[r]) > 100 && g_faraway)
					{
						g_faraway = true;
						g_snd_recharge[r][id] = false;
					}
					if(g_snd_recharge[r][id] == true) emit_sound(g_recharge_id[r], CHAN_WEAPON, "stz/HealthArmor-Stations/ArmorRecharge.wav", 1.0, ATTN_NORM, SND_STOP, PITCH_NORM);
				}
			}
			else
			{
				log_amx("Error: Failure in map config! Please make a new one. (Armor-Station nr: %d failed to load)",r);
			}	
		}
		//~~ Calculate the next Checking time ~~
		if(g_faraway) g_chargesteppfrequency = 1.0;
		else g_chargesteppfrequency = 0.2;
		g_nextstep[id] = gametime + g_chargesteppfrequency; //Add a little delay for checking
		g_faraway = true;
	}
	return FMRES_HANDLED;
}



//*****************************************************************************************************************
//*************************************************   M E N U S   *************************************************
//*****************************************************************************************************************

// Display the Selection Menu
public display_select(id)
{	
	static szMenuBody[224];
	new nKeys;
	if((g_medkit_count < MAXMEDKITS) && (g_recharge_count < MAXRECHARGES))
	{
		nKeys = (1<<9)|(1<<7)|(1<<1)|(1<<0);
		formatex(szMenuBody, 223, "Choose a type: ^n^n1. medkit^n2. recharge^n^n8. Save this Position!^n^n0. Exit");
	}
	else if((g_medkit_count < MAXMEDKITS) && (g_recharge_count == MAXRECHARGES))
	{
		nKeys = (1<<9)|(1<<7)|(1<<1)|(1<<0);
		formatex(szMenuBody, 223, "Choose a type: ^n^n1. medkit^n2. \rrecharge\w^n^n8. Save this Position!^n^n0. Exit");		
	}
	else if((g_recharge_count < MAXRECHARGES) && (g_medkit_count == MAXMEDKITS)) 
	{
		nKeys = (1<<9)|(1<<7)|(1<<1)|(1<<0);
		formatex(szMenuBody, 223, "Choose a type: ^n^n1. \rmedkit\w^n2. recharge^n^n8. Save this Position!^n^n0. Exit");		
	}
	else if((g_medkit_count == MAXMEDKITS) && (g_recharge_count == MAXRECHARGES))
	{
		nKeys = (1<<9)|(1<<7)|(1<<1)|(1<<0);
		formatex(szMenuBody, 223, "You have all available Stations placed!^n^n1. \rmedkit\w^n2. \rrecharge\w^n^n8. \rSave this Position!\w^n^n0. Exit");
	}
	show_menu(id, nKeys, szMenuBody, -1, "select_menu" );
	return;
}

// Check what Key was pressed in the Selection Menu
public action_select(id, key)
{
	switch(key)
	{
		case 0: // medkit
		{
			if(g_medkit_count < MAXMEDKITS && pev_valid(g_entity))
			{
				g_curmodeltype = 0;
				engfunc(EngFunc_SetModel, g_entity, g_models[g_curmodeltype]);
				set_pev(g_entity, pev_classname, MEDKITCLASS);
				new Float:mins[3] = {-2.0, -2.0, 38.0};
				new Float:maxs[3] = {2.0, 2.0, 42.0};
				engfunc(EngFunc_SetSize, g_entity, mins, maxs);
				setGlow(g_entity);
				display_select(id);
			}else display_select(id);
		}
		case 1: // recharge
		{
			if(g_recharge_count < MAXRECHARGES && pev_valid(g_entity))
			{
				g_curmodeltype = 1;
				engfunc(EngFunc_SetModel, g_entity, g_models[g_curmodeltype]);
				set_pev(g_entity, pev_classname, RECHARGECLASS);
				new Float:mins[3] = {-2.0, -2.0, 38.0};
				new Float:maxs[3] = {2.0, 2.0, 42.0};
				engfunc(EngFunc_SetSize, g_entity, mins, maxs);				
				setGlow(g_entity);
				display_select(id);
			}else display_select(id);
		}
		case 7:	
		{
			if((g_recharge_count < MAXRECHARGES) || (g_medkit_count < MAXMEDKITS))
			{
				display_save(id);
			}else	display_select(id);
		}
		case 9:	if(pev_valid(g_entity)) engfunc(EngFunc_RemoveEntity, g_entity);
	}
}

// Display the Save Menu
public display_save(id)
{
	show_menu(id, (1<<0)|(1<<1), "Save this Medkit/Recharger?^n^n1. Yes, save it.^n2. No, delete it.^n", -1, "save_menu");
}

// Check what Key was pressed in the Save Menu
public action_save(id, key)
{
	switch (key)
	{
		case 0: save_pos();
		case 1:
		{
			if(pev_valid(g_entity))
			{
				engfunc(EngFunc_RemoveEntity, g_entity);
			}
		}
	}
}



//*****************************************************************************************************************
//***************************************   E N T I T Y H A N D L I N G   *****************************************
//*****************************************************************************************************************

//+++++ PLACE STATION ++++++
public cmd_place_station(id)
{
	if(!(get_user_flags(id) & ADMIN_ACCESS_LEVEL))
	{
		client_print(id, print_console, "You do not have access to this command.");
		return PLUGIN_HANDLED;
	}
	g_curAdjuster = id;
	new cmd[2];
	read_argv(0, cmd, 1);
	switch(cmd[0])
	{
		case '+':
		{
			if(g_adjusting)
			{
				log_amx("Error: Someone is already placing an Medkit/Recharge");
				client_print(0, print_chat, "Error: Another user is already placing an Medkit/Recharge");
				return PLUGIN_HANDLED;
			}
			if(pev_valid(g_entity)) engfunc(EngFunc_RemoveEntity, g_entity);
			if(!pev_valid(g_entity))
			{
				if(g_medkit_count < MAXMEDKITS || g_recharge_count < MAXRECHARGES) entcreate();
				else
				{
					log_amx("Error: You have placed all available Medkits/Recharges");
					client_print(0, print_chat, "Error: You have placed all available Medkits/Recharges");
					return PLUGIN_HANDLED;
				}
			}
			g_adjusting = true;
		}
		case '-':
		{
			g_adjusting = false;
			if(pev_valid(g_entity) && g_entity != 0) display_select(id);
		}
	}
	return PLUGIN_HANDLED;
}


//+++++ DELETE STATION +++++
public del_station(id)
{
	if(!(get_user_flags(id) & ADMIN_ACCESS_LEVEL))
	{
		client_print(id, print_console, "You do not have access to this command.");
		return PLUGIN_HANDLED;
	}
	
	new ent = get_ent_in_aim_radius(id, 30.0);
	new num = get_station_num(ent);
	
	if(num == -1) return PLUGIN_HANDLED_MAIN;
	
	new class[33];
	pev(ent, pev_classname, class, 32);
	if(equal(class, MEDKITCLASS)) delete_saved_stations(num, 1);
	else delete_saved_stations(num, 2);
	return PLUGIN_CONTINUE;
}


//+++++ CREATE ENTITY ++++++
public entcreate()
{		
	if(g_medkit_count == MAXMEDKITS) g_curmodeltype = 1;
	if(g_recharge_count == MAXRECHARGES) g_curmodeltype = 0;
	
	g_entity = engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, "info_target"));
	engfunc(EngFunc_SetModel, g_entity, g_models[g_curmodeltype]);
	
	if(g_curmodeltype == 0) set_pev(g_entity, pev_classname, MEDKITCLASS);
	else set_pev(g_entity, pev_classname, RECHARGECLASS);
	
	set_pev(g_entity, pev_controller_0, 125);
	set_pev(g_entity, pev_controller_1, 125);
	set_pev(g_entity, pev_controller_2, 125);
	set_pev(g_entity, pev_controller_3, 125);
	
	new Float:mins[3] = {-2.0, -2.0, 38.0};
	new Float:maxs[3] = {2.0, 2.0, 42.0};
	engfunc(EngFunc_SetSize, g_entity, mins, maxs);
	
	set_pev(g_entity, pev_solid, 2);
	
	setGlow(g_entity);
}


//+++++ LET THE STATION GLOW +++++
setGlow(ent)
{
	if(g_cvar_gloweffect && pev_valid(ent))
	{
		new class[32];
		pev(ent, pev_classname, class, 31);
		set_pev(ent, pev_renderfx, kRenderFxHologram);
		if(equal(class, MEDKITCLASS)) set_pev(ent, pev_rendercolor, g_colors[0]); // red for the Medkit-Station
		else set_pev(ent, pev_rendercolor, g_colors[1]); // blue for the Recharge-Station

		set_pev(ent, pev_renderfx, kRenderFxGlowShell);
		set_pev(ent, pev_renderamt, 255.0);
		set_pev(ent, pev_rendermode, kRenderTransAlpha);
	}
}


//+++++ MOVE THE ENTITY ++++++
public pull_station(id)
{
	move_station(id, 1);
}

public push_station(id)
{
	move_station(id, 2);
}

public move_station(id, flag)
{
	if(!(get_user_flags(id) & ADMIN_ACCESS_LEVEL))
	{
		client_print(id, print_console, "You do not have access to this command.");
		return PLUGIN_HANDLED;
	}
	if(pev_valid(g_entity))
	{
		static Float:player_origin[3], Float:distance[3], greatest;
		pev(id, pev_origin, player_origin);
		distance[0] = abs_f(player_origin[0] - g_aimOrigin[2][0]);
		distance[1] = abs_f(player_origin[1] - g_aimOrigin[2][1]);
		distance[2] = abs_f(player_origin[2] - g_aimOrigin[2][2]);
		for(new i = 0; i < 3; i++)
		{
			if(distance[i] > distance[greatest]) greatest = i;
		}
		switch(flag)
		{
			case 1: {g_aimOrigin[2][greatest] += (player_origin[greatest] > g_aimOrigin[2][greatest] ? DISTANCE : -DISTANCE);}
			case 2: {g_aimOrigin[2][greatest] -= (player_origin[greatest] > g_aimOrigin[2][greatest] ? DISTANCE : -DISTANCE);}
			case 3: {g_aimOrigin[2][greatest] += (player_origin[greatest] > g_aimOrigin[2][greatest] ? 2.0 : -2.0);}
		}
		engfunc(EngFunc_SetOrigin, g_entity, g_aimOrigin[2]);
	}
	return 1;
}



//*****************************************************************************************************************
//************************************************   F U N C T I O N S  *******************************************
//*****************************************************************************************************************

//+++++ Taken from fakemeta_util.inc (very nice! many thanks to VEN from http://forums.alliedmods.net/index.php +++++
bool:is_in_viewcone(index, const Float:point[3])
{
	new Float:angles[3]
	pev(index, pev_angles, angles)
	engfunc(EngFunc_MakeVectors, angles)
	global_get(glb_v_forward, angles)
	angles[2] = 0.0

	new Float:origin[3], Float:diff[3], Float:norm[3]
	pev(index, pev_origin, origin)
	vec_sub(point, origin, diff)
	diff[2] = 0.0
	vec_normalize(diff, norm)

	new Float:dot, Float:fov
	dot = vec_dot(norm, angles)
	pev(index, pev_fov, fov)
	if (dot >= floatcos(fov * M_PI / 360))
		return true

	return false
}

get_aim_origin(index, Float:origin[3])
{
	static Float:start[3], Float:view_ofs[3];
	pev(index, pev_origin, start);
	pev(index, pev_view_ofs, view_ofs);
	vec_add(start, view_ofs, start);
	
	static Float:dest[3];
	pev(index, pev_v_angle, dest);
	engfunc(EngFunc_MakeVectors, dest);
	global_get(glb_v_forward, dest);
	vec_mul_scalar(dest, 9999.0, dest);
	vec_add(start, dest, dest);
	
	engfunc(EngFunc_TraceLine, start, dest, 0, index, 0);
	get_tr2(0, TR_vecEndPos, origin);
	
	return 1;
}

bool:is_aiming_at_sky(index)
{
	new target, temp;
	get_user_aiming(index,target,temp);
	if(engfunc(EngFunc_PointContents,target) == CONTENTS_SKY) return true;
	return false;
}

get_ent_in_aim_radius(index, Float:radius) 
{
	static Float:start[3], Float:view_ofs[3];
	static Float:dest[3], Float:origin[3], entclass[32];
	new ent = -1;
	
	pev(index, pev_origin, start)
	pev(index, pev_view_ofs, view_ofs)
	vec_add(start, view_ofs, start)
	pev(index, pev_v_angle, dest)
	engfunc(EngFunc_MakeVectors, dest)
	global_get(glb_v_forward, dest)
	vec_mul_scalar(dest, 9999.0, dest)
	vec_add(start, dest, dest)
	engfunc(EngFunc_TraceLine, start, dest, 0, index, 0)
	get_tr2(0, TR_vecEndPos, origin)
	while((ent = engfunc(EngFunc_FindEntityInSphere, ent, origin, radius)) != 0)
	{
		pev(ent, pev_classname, entclass, 32)
		if(equal(entclass, MEDKITCLASS) || equal(entclass, RECHARGECLASS)) return ent;
	}
	return 0
}

Float:ent_distance(ent1, ent2)
{
	new Float:mins1[3], Float:maxs1[3];
	new Float:mins2[3], Float:maxs2[3];
	new Float:dist[3];
	pev(ent1, pev_absmin, mins1);
	pev(ent1, pev_absmax, maxs1);
	pev(ent2, pev_absmin, mins2);
	pev(ent2, pev_absmax, maxs2);
	for (new i = 0; i < 3; ++i)
	{
		if (mins1[i] > maxs2[i]) dist[i] = mins1[i] - maxs2[i];
		else if (mins2[i] > maxs1[i]) dist[i] = mins2[i] - maxs1[i];
	}
	return vector_length(dist);
}

/*bool:is_visible(index, const Float:point[3], ignoremonsters = 0)
{
	new Float:start[3], Float:view_ofs[3];
	pev(index, pev_origin, start);
	pev(index, pev_view_ofs, view_ofs);
	vec_add(start, view_ofs, start);

	engfunc(EngFunc_TraceLine, start, point, ignoremonsters, index, 0);

	new Float:fraction;
	get_tr2(0, TR_flFraction, fraction);
	if (fraction == 1.0)
		return true;

	return false;
}*/

minimize_normal(Float:normal[3])
{
	normal[0] /= 10.0;
	normal[1] /= 10.0;
	normal[2] /= 10.0;
	return 1;
}

Float:abs_f(Float:x)
{
	if(x < 0) return (-1.0 * x);
	return x;
}

equal_f(Float:origin1[3], Float:origin2[3])
{
	new num_equal = (origin1[0] == origin2[0] ? 1 : 0);
	num_equal += (origin1[1] == origin2[1] ? 1 : 0);
	num_equal += (origin1[2] == origin2[2] ? 1 : 0);
	return num_equal;
}

Float:sum_f(Float:origin1[3], Float:origin2[3])
{
	new Float:result[3];
	result[0] = origin1[0] + origin2[0];
	result[1] = origin1[1] + origin2[1];
	result[2] = origin1[2] + origin2[2];
	return result;
}

Float:diff_f(Float:origin1[3], Float:origin2[3])
{
	new Float:result[3];
	result[0] = origin1[0] - origin2[0];
	result[1] = origin1[1] - origin2[1];
	result[2] = origin1[2] - origin2[2];
	return result;
}

Float:cross_product(Float:origin1[3], Float:origin2[3])
{
	new Float:result[3];
	result[0] = origin1[1]*origin2[2] - origin1[2]*origin2[1];
	result[1] = origin1[2]*origin2[0] - origin1[0]*origin2[2];
	result[2] = origin1[0]*origin2[1] - origin1[1]*origin2[0];
	return result;
}


//+++++ Taken from xs.inc (very nice! Many thanks to PM from http://forums.alliedmods.net/index.php +++++
vec_add(const Float:in1[], const Float:in2[], Float:out[])
{
	out[0] = in1[0] + in2[0];
	out[1] = in1[1] + in2[1];
	out[2] = in1[2] + in2[2];
}

vec_sub(const Float:in1[], const Float:in2[], Float:out[])
{
	out[0] = in1[0] - in2[0];
	out[1] = in1[1] - in2[1];
	out[2] = in1[2] - in2[2];
}

vec_mul_scalar(const Float:vec[], Float:scalar, Float:out[])
{
	out[0] = vec[0] * scalar;
	out[1] = vec[1] * scalar;
	out[2] = vec[2] * scalar;
}

vec_normalize(const Float:vec[], Float:out[])
{
	new Float:invlen = xs_rsqrt(vec[0]*vec[0] + vec[1]*vec[1] + vec[2]*vec[2]);
	out[0] = vec[0] * invlen;
	out[1] = vec[1] * invlen;
	out[2] = vec[2] * invlen;
}

Float:xs_rsqrt(Float:x)
{
	return 1.0 / floatsqroot(x);
}
	
Float:vec_dot(const Float:vec1[], const Float:vec2[])
{
	return vec1[0]*vec2[0] + vec1[1]*vec2[1] + vec1[2]*vec2[2];
}

get_station_num(id)
{
	for(new m = 0; m < g_medkit_count; m++)
		if(g_medkit_id[m] == id) return m;

	for(new r = 0; r < g_recharge_count; r++)
		if(g_recharge_id[r] == id) return r;

	return -1;
}

//+++++ Manipulate the user armor ++++++
set_realarmor(id, armor=2)
{
	if(is_module_loaded("cstrike") != -1)
	{
		set_pdata_int(id, OFFSET_ARMORTYPE, armor, OFFSET_LINUX);
		message_begin(MSG_ONE, g_umsgA, {0,0,0}, id);
		write_byte(1);
		message_end();
	}
}
Предполагам го направих да не дава кръв ако играчът има 100 или над 100.

Аватар
LoShIaA
Извън линия
Потребител
Потребител
Мнения: 323
Регистриран на: 20 Окт 2016, 14:44
Местоположение: Стара Загора
Се отблагодари: 120 пъти
Получена благодарност: 9 пъти

Health Armor Stations плъгина да не ти прави 100 кръвта, когато имаш над 100 и използваш станция

Мнение от LoShIaA » 22 Окт 2017, 21:29

Работи правилно, но много се извинявам може ли и за бронята да го оправиш, че то така както съм го написал в темата не се разбира, че искам и бронята.

Аватар
OciXCrom
Извън линия
Администратор
Администратор
Мнения: 7206
Регистриран на: 06 Окт 2016, 19:20
Местоположение: /resetscore
Се отблагодари: 117 пъти
Получена благодарност: 1295 пъти
Обратна връзка:

Health Armor Stations плъгина да не ти прави 100 кръвта, когато имаш над 100 и използваш станция

Мнение от OciXCrom » 22 Окт 2017, 22:39

Код за потвърждение: Избери целия код

/**********************************************************************************
* 									Health/Armor-Stations
*
*
* Author: regalis ([email protected])
*
*
*	Version: 0.3.5
*
*
*
*	Description:
*		Do you know HalfLife Deathmatch?
*		There are Stations to recharge your Health and you Armor.
*		Now you can have these Station in Counterstrike too!
*		Place the Stations you want where you want ;)
*
*		To place a Station make sure you are an admin and bind a key to "+place_station".
*		Now press the key and aim at where you want to place the station, release the key to choose which sort of station you want to place.
*		With the commands "push_station" and "pull_station" you can pull or push the station in the direction you are looking.
*		If you have choosen the station which fits your needs you can save it to the config-file which is automaticaly created for each map.
*		That all...
*		To use these Stations just stand near it and press your USE-key (standard: E)
*		The reloading of the Station is triggered as soon as the Station gets empty!
*
*
*
*
*	Admin-Commands:
*		"+place_station" - Place an Health/Armor-Station on the wall in front of you
*		"push_station" - Move the Health/Armor-Station away of you
*		"pull_station" - Move the Health/Armor-Station closer to you
*		"del_station" - Delete the Healt/Armor-Station at which you aim
*
*
*
* CVARS:
*		HA_maxhealth - How much health is in a HealthStation for everyone [number of HP](0-100) (Default: 40 HP)
*		HA_maxplayerhealth - Set the maximum amount of health a player can charge [100 - 255] (Default: 255 HP)
*		HA_healthpersec - Set the amount of HP a player get per chargecycle [1 - ?] (Default: 4 HP should be 8-12 HP per second) 
*		HA_maxarmor - How much armor is in a ArmorStation for everyone [number of AP]	(0-100)	(Default: 40 AP)
*		HA_maxplayerarmor - Set the maximum amount of armor a player can charge [100 - 255] (Default: 255 AP)
*		HA_armorpersec - Set the amount of AP a player get per chargecycle [1 - ?] (Default: 4 AP should be 8-12 AP per second)
*		HA_healthreloadtime - How long the player have to wait till he can use the same HealthStation again [number in seconds](Default: 30 sec)
*		HA_armorreloadtime - How long the player have to wait till he can use the same ArmorStation again [number in seconds]	(Default: 30 sec)
*		HA_gloweffect - Let the HealthStations glow red and the ArmorStations glow blue [0|1]	(on|off) (Default: 1)
*		
*
*
*	Requirements:
*		Fakemeta-Modul
*
*
*
*	Changelog:
*		v0.1:
*			@ initial release
*
*		v0.2:
*			! Fixed a sound bug
*			+ Added support for newly placed station giving HP/AP
*			+ Added 4 new CVARS for more customization
*
*		v0.3:
*			- Removed static declaration for global Variables
*			- Removed "stock" for functions
*			+ Added a function to delete placed stations
*			+ Added real armor to the stations (only for Counterstrike)
*		
*		v0.3.1:
*			! fixed a bug with realarmor(it is only for CounterStrike)
*
*		v0.3.5:
*			!fixed a bug when you placed a station at the sky/ceiling the server crashed...now it is handled
*
*
* Known Bugs:
*		- At some placing angles the station looks black
*			(Workaround: Just place it from another angle)
*
*
*	TODO:
*		- maybe optimizing a little
*
*
*	Credits:
*		stupok69 for his nice In-Game-Ads where i have taken the Station placing (http://forums.alliedmods.net/showthread.php?p=424583)
*		Cheap_suit for his help here: (http://forums.alliedmods.net/showpost.php?p=482976&postcount=4)
*		Alka for the help on fixing the bug with the "placing at the sky/ceiling"
*		Simon Logic for his idea with Armour-Absence-Fix Plugin here: (http://forums.alliedmods.net/showthread.php?t=55591)
*		VEN for his fakemeta_util.inc here: (http://forums.alliedmods.net/showthread.php?t=28284)
*		PM for his xs.inc
*
*
***********************************************************************************/
#include <amxmodx>
#include <amxmisc>
#include <fakemeta>


//++++++++++++++++++++
//+++++ DEFINES ++++++
//++++++++++++++++++++
// Define the offset for the Armor manipulation stock
#if cellbits == 32
	#define OFFSET_ARMORTYPE 112
#else
	#define OFFSET_ARMORTYPE 137
#endif
#define OFFSET_LINUX 5

#define CONFIGFOLDER "HA-Stations"
#define PLACESTEPFREQUENCY 10
#define DISTANCE 3.0
#define ADMIN_ACCESS_LEVEL ADMIN_BAN
#define MAXPLAYERS 32
#define MAXMEDKITS 15
#define MAXRECHARGES 15
#define MEDKITCLASS "ha_medkit"
#define RECHARGECLASS "ha_recharge"
#define SND_STOP (1<<5)

// Define the Author :P 
#define PLUGIN "Healt&Armor-Stations"
#define VERSION "0.3.5"
#define AUTHOR "regalis"


//+++++++++++++++++++++++++++++
//+++++ GLOBAL VARIABLES ++++++
//+++++++++++++++++++++++++++++
// The models
new const g_models[][] =
{
	"models/stz/HealthArmor-Stations/HealthStation.mdl",
	"models/stz/HealthArmor-Stations/ArmorStation.mdl"
}
new const gModelIndex = sizeof g_models;

// The Glow colors
new const Float:g_colors[][3] = {
	{255.0, 0.0, 0.0},
	{0.0, 0.0, 255.0}
}

// ################## FOR FUTURE USAGE #################
//new static bool:g_restart_attempt[33];
// ################## FOR FUTURE USAGE #################


//+++++ MESSAGE IDs ++++++
new g_umsgA;
//new g_msgM;
	
	
//+++++ Adminstuff + Filehandling +++++
new g_prethink_placestepper;
new g_curmodeltype;
new g_entity;
new g_curAdjuster = -1;
new Float:g_aimOrigin[3][3];
new Float:g_entity_angles[3];
new g_file_name[256]
new g_map_name[32];
new bool:g_adjusting = false;

//+++++ Deleting +++++
new g_del_num;
new g_del_models[MAXMEDKITS+MAXRECHARGES];
new Float:g_del_origins[MAXMEDKITS+MAXRECHARGES][3];
new Float:g_del_angles[MAXMEDKITS+MAXRECHARGES][3];

//+++++ Checking the usage +++++
new Float:g_nextstep[MAXPLAYERS+1];
new Float:g_chargesteppfrequency = 0.5;
new bool:g_faraway;
new g_cvar_gloweffect;

// Medkit
new Float:g_medkit_coords[MAXMEDKITS][3];
new Float:g_medkit_angles[MAXMEDKITS][3];
new g_medkit_id[MAXMEDKITS];
new g_medkit_count;

// Recharge
new Float:g_recharge_coords[MAXRECHARGES][3];
new Float:g_recharge_angles[MAXRECHARGES][3];
new g_recharge_id[MAXRECHARGES];
new g_recharge_count;


//+++++ Healthhandling +++++
new g_medkit_value[MAXMEDKITS][MAXPLAYERS+1];
new bool:g_snd_medkit[MAXMEDKITS][MAXPLAYERS+1];
new g_cvar_maxhealth;
new g_cvar_maxplayerhealth;
new g_cvar_healthpersec
new Float:g_cvar_medkitreloadtime;
new g_pHealth[MAXPLAYERS+1];


//+++++ Armorhandling +++++
new g_recharge_value[MAXRECHARGES][MAXPLAYERS+1];
new bool:g_snd_recharge[MAXRECHARGES][MAXPLAYERS+1];
new g_cvar_maxarmor;
new g_cvar_maxplayerarmor;
new g_cvar_armorpersec;
new Float:g_cvar_rechargereloadtime;
new g_pArmor[MAXPLAYERS+1];


//+++++ GLOBAL CVAR POINTER ++++++
new gcvar_maxhealth;
new gcvar_maxplayerhealth;
new gcvar_medkitreloadtime;
new gcvar_healthpersec
new gcvar_maxarmor;
new gcvar_maxplayerarmor;
new gcvar_rechargereloadtime;
new gcvar_armorpersec;
new gcvar_gloweffect;



//++++++++++++++++++++++++
//+++++ PLUGIN-INIT ++++++
//++++++++++++++++++++++++
public plugin_init()
{
	register_plugin(PLUGIN, VERSION, AUTHOR);
	register_cvar(PLUGIN, VERSION, FCVAR_SERVER);
	
	//+++++ cvar pointer ++++++
	gcvar_maxhealth = register_cvar("HA_maxhealth", "40");
	gcvar_maxplayerhealth = register_cvar("HA_maxplayerhealth", "100");
	gcvar_healthpersec = register_cvar("HA_healthpersec", "2")
	gcvar_maxarmor = register_cvar("HA_maxarmor", "40");
	gcvar_maxplayerarmor = register_cvar("HA_maxplayerarmor", "100");
	gcvar_armorpersec = register_cvar("HA_armorpersec", "2");
	gcvar_medkitreloadtime = register_cvar("HA_healthreloadtime", "20");
	gcvar_rechargereloadtime = register_cvar("HA_armorreloadtime", "20");
	gcvar_gloweffect = register_cvar("HA_gloweffect", "1");
	
	//+++++ Admin Commands +++++
	register_clcmd("+place_station", "cmd_place_station", ADMIN_ACCESS_LEVEL);
	register_clcmd("-place_station", "cmd_place_station", ADMIN_ACCESS_LEVEL);
	register_clcmd("pull_station", "pull_station", ADMIN_ACCESS_LEVEL);
	register_clcmd("push_station", "push_station", ADMIN_ACCESS_LEVEL);
	register_clcmd("del_station", "del_station", ADMIN_ACCESS_LEVEL);
	
	//+++++ Menu Commands +++++
	register_menucmd(register_menuid("save_menu"), (1<<0)|(1<<1), "action_save");
	register_menucmd(register_menuid("select_menu"), 1023, "action_select");
	
	//################## FOR FUTURE USAGE #################
	/*
	//+++++ Client Commands ++++++
	register_clcmd("fullupdate", "clcmd_fullupdate");
	//+++++ Events ++++++
	register_event("ResetHUD", "event_hud_reset", "be");
	register_event("TextMsg", "event_restart_attempt", "a", "2=#Game_will_restart_in");
	*/
	//################## FOR FUTURE USAGE #################
	
	//+++++ Message ID +++++
	g_umsgA = get_user_msgid("ArmorType");
	//g_umsgM = get_user_msgid("Money");
	
	//+++++ Logevents ++++++
	register_logevent("event_roundStart", 2, "1=Round_Start");
	register_logevent("event_round_end", 2, "1=Round_End");
	
	//+++++ Forwards +++++
	register_forward(FM_PlayerPreThink, "PreThink");
	
	//+++++ Read the Config +++++
	readCvars();
	
	//+++++ Load the saved Stations +++++
	load_saved_stations(g_file_name);
}



//++++++++++++++++++++++++++++
//+++++ PLUGIN-PRECACHE ++++++
//++++++++++++++++++++++++++++
public plugin_precache()
{
	new configs_dir[64];
	get_configsdir(configs_dir, 63);
	get_mapname(g_map_name, 31);
	
	// Save the Configfilename in a global variable
	formatex(g_file_name, 255, "%s/%s", configs_dir, CONFIGFOLDER);
	if(!dir_exists(g_file_name)) mkdir(g_file_name);
	formatex(g_file_name, 255, "%s/%s/%s.txt", configs_dir, CONFIGFOLDER, g_map_name);
	
	// Precache the models
	for(new m = 0; m < gModelIndex; m++) engfunc(EngFunc_PrecacheModel,g_models[m]);
	
	
	// Precache the sounds
	precache_sound("stz/HealthArmor-Stations/ArmorRecharge.wav");
	precache_sound("stz/HealthArmor-Stations/ArmorRechargeOk.wav");
	precache_sound("stz/HealthArmor-Stations/ArmorRechargeNo.wav");
	precache_sound("stz/HealthArmor-Stations/HealthRecharge.wav");
	precache_sound("stz/HealthArmor-Stations/HealthRechargeOk.wav");
	precache_sound("stz/HealthArmor-Stations/HealthRechargeNo.wav");
}




//*****************************************************************************************************************
//****************************************   G E N E R A L S T U F F   ********************************************
//*****************************************************************************************************************

//################## FOR FUTURE USAGE #################
/* 
//+++++ CLIENT COMMAND FULLUPDATE ++++++
public clcmd_fullupdate()
{
	return PLUGIN_HANDLED_MAIN;
}

//+++++ Event RESTART-ATTEMPT ++++++
public event_restart_attempt()
{
	new players[32], num;
	get_players(players, num, "a");
	for (new i; i < num; ++i)
	{
		g_restart_attempt[players[i]] = true;
	}
}

//+++++ Event HUD-RESET ++++++
public event_hud_reset(id)
{
	if (g_restart_attempt[id])
	{
		g_restart_attempt[id] = false;
		return;
	}
	event_player_spawn(id);
}

//+++++ Event PLAYERSPAWN ++++++
public event_player_spawn(id)
{
	// nothing to do...maybe later ;)
}
*/
//################## FOR FUTURE USAGE #################

//+++++ Event ROUNDSTART ++++++
public event_roundStart()
{
	readCvars();
	resetStations();
}

public event_round_end()
{
	resetStations();
}

//+++++ READ THE CVARS +++++++
readCvars()
{
	// Putting the CVARS in the global variables
	g_cvar_maxarmor = get_pcvar_num(gcvar_maxarmor);
	g_cvar_maxplayerarmor = get_pcvar_num(gcvar_maxplayerarmor);
	g_cvar_armorpersec = get_pcvar_num(gcvar_armorpersec);
	g_cvar_maxhealth = get_pcvar_num(gcvar_maxhealth);
	g_cvar_maxplayerhealth = get_pcvar_num(gcvar_maxplayerhealth);
	g_cvar_healthpersec = get_pcvar_num(gcvar_healthpersec);
	g_cvar_rechargereloadtime = get_pcvar_float(gcvar_rechargereloadtime);
	g_cvar_medkitreloadtime = get_pcvar_float(gcvar_medkitreloadtime);
	g_cvar_gloweffect = get_pcvar_num(gcvar_gloweffect);
}



//*****************************************************************************************************************
//*****************************************   S T A T I O N H A N D L I N G   *************************************
//*****************************************************************************************************************

//+++++ RESET THE STATIONS +++++++
resetStations()
{
	for (new i=0; i < 32; i++)
	{
		// Reset medkit-Stations to the cvar value
		for(new m = 0; m < g_medkit_count; m++)
		{
			if(task_exists(434774+i+m))	 remove_task(434774+i+m);
			g_medkit_value[m][i] = g_cvar_maxhealth;
			if(g_snd_medkit[m][i])
			{
				emit_sound(g_medkit_id[m], CHAN_WEAPON, "stz/HealthArmor-Stations/HealthRecharge.wav", 1.0, ATTN_NORM, SND_STOP, PITCH_NORM);
				g_snd_medkit[m][i] = false;
			}
		}
		
		// Reset recharge-Stations to the cvar value
		for(new r = 0; r < g_recharge_count; r++)
		{
			if(task_exists(477434+i+r))	 remove_task(477434+i+r);
			g_recharge_value[r][i] = g_cvar_maxarmor;
			if(g_snd_recharge[r][i])
			{
				emit_sound(g_recharge_id[r], CHAN_WEAPON, "stz/HealthArmor-Stations/ArmorRecharge.wav", 1.0, ATTN_NORM, SND_STOP, PITCH_NORM);
				g_snd_recharge[r][i] = false;
			}
		}
	}
}


//+++++ RESET A HEALTH STATION +++++
public reset_HealthStation(param[2])
{
	// Get the params
	new id = param[0];
	new number = param[1];
	
	// Reset the value of the certain Station to the value stored in the cvar
	g_medkit_value[number][id] = g_cvar_maxhealth;
}


//+++++ RESET A ARMOR STATION +++++
public reset_ArmorStation(param[2])
{
	// Get the params
	new id = param[0];
	new number = param[1];
	
	// Reset the value of the certain Station to the value stored in the cvar
	g_recharge_value[number][id] = g_cvar_maxarmor;
}


remove_stations()
{
	new ent = -1;
	while((ent = engfunc(EngFunc_FindEntityByString, -1, "classname", MEDKITCLASS)) != 0)
	{
		if(pev_valid(ent))
		{
			engfunc(EngFunc_RemoveEntity, ent);
		}
	}
	ent = -1;
	while((ent = engfunc(EngFunc_FindEntityByString, -1, "classname", RECHARGECLASS)) != 0)
	{
		if(pev_valid(ent))
		{
			engfunc(EngFunc_RemoveEntity, ent);
		}
	}
	g_del_num = 0;
	g_medkit_count = 0;
	g_recharge_count = 0;
}


//*****************************************************************************************************************
//********************************   H E A L T H - A R M O R H A N D L I N G  *************************************
//*****************************************************************************************************************

//+++++ Give the player health +++++
GiveHealth(id, number)
{
	if(g_medkit_value[number][id] > 0)
	{
		// The HealthValue in the current station for this player is more than 0
		g_pHealth[id] = pev(id, pev_health); // Get the player health
		if(g_pHealth[id] <= g_cvar_maxplayerhealth-g_cvar_healthpersec)
		{
			g_medkit_value[number][id] -= g_cvar_healthpersec; // subtract the given Healthvalue from the Health-Station value
			set_pev(id, pev_health, float(g_pHealth[id]+g_cvar_healthpersec)); // Give the player the Health
			if(!g_snd_medkit[number][id])
			{
				emit_sound(g_medkit_id[number], CHAN_WEAPON, "stz/HealthArmor-Stations/HealthRecharge.wav", 1.0, ATTN_NORM, 0, PITCH_NORM);
			}
		}
		else
		{
			if(g_pHealth[id] == g_cvar_maxplayerhealth)
			{
				emit_sound(g_medkit_id[number], CHAN_WEAPON, "stz/HealthArmor-Stations/HealthRecharge.wav", 1.0, ATTN_NORM, SND_STOP, PITCH_NORM);
				emit_sound(g_medkit_id[number], CHAN_STREAM, "stz/HealthArmor-Stations/HealthRechargeNo.wav", 1.0, ATTN_NORM, 0, PITCH_NORM);
			}
			else
			{
				set_pev(id, pev_health, float(g_cvar_maxplayerhealth));
				emit_sound(g_medkit_id[number], CHAN_WEAPON, "stz/HealthArmor-Stations/HealthRecharge.wav", 1.0, ATTN_NORM, SND_STOP, PITCH_NORM);
				emit_sound(id, CHAN_STREAM, "stz/HealthArmor-Stations/HealthRechargeOk.wav", 1.0, ATTN_NORM, 0, PITCH_NORM);
			}
		}
	}
	else
	{
		emit_sound(g_medkit_id[number], CHAN_WEAPON, "stz/HealthArmor-Stations/HealthRecharge.wav", 1.0, ATTN_NORM, SND_STOP, PITCH_NORM);
		emit_sound(g_medkit_id[number], CHAN_STREAM, "stz/HealthArmor-Stations/HealthRechargeNo.wav", 1.0, ATTN_NORM, 0, PITCH_NORM);
		// Health-Station is empty
		if(!task_exists(434774+id+number))
		{
			new param[2];
			param[0] = id;
			param[1] = number;
			// Plan a task to refresh the Health-Station value
			set_task(g_cvar_medkitreloadtime, "reset_HealthStation", 434774+id+number, param, 2);
		}
	}
}

//+++++ Give the player armor +++++
GiveArmor(id, number)
{
	if(g_recharge_value[number][id] > 0)
	{
		// The ArmorValue in the current station for this player is more than 0
		g_pArmor[id] = pev(id, pev_armorvalue); // Get the player armor
		if(g_pArmor[id] <= g_cvar_maxplayerarmor-g_cvar_armorpersec)
		{
			// Player have a lower ArmorValue than 100
			g_recharge_value[number][id] -= g_cvar_armorpersec;	// Subtract the given armor from the Armor-Station value
			if(!get_pdata_int(id, OFFSET_ARMORTYPE, OFFSET_LINUX)) set_realarmor(id);
			set_pev(id, pev_armorvalue, float(g_pArmor[id]+g_cvar_armorpersec)); // Give the player the Armor
			
			if(!g_snd_recharge[number][id])
			{
				emit_sound(g_recharge_id[number], CHAN_WEAPON, "stz/HealthArmor-Stations/ArmorRecharge.wav", 1.0, ATTN_NORM, 0, PITCH_NORM);
			}
		}
		else
		{
			if(g_pArmor[id] == g_cvar_maxplayerarmor)
			{
				emit_sound(g_recharge_id[number], CHAN_WEAPON, "stz/HealthArmor-Stations/ArmorRecharge.wav", 1.0, ATTN_NORM, SND_STOP, PITCH_NORM);
				emit_sound(g_recharge_id[number], CHAN_STREAM, "stz/HealthArmor-Stations/ArmorRechargeNo.wav", 1.0, ATTN_NORM, 0, PITCH_NORM);
			}
			else
			{
				set_pev(id, pev_armorvalue, float(g_cvar_maxplayerarmor)); // If player have between 96-100 Armor set it to 100
				emit_sound(g_recharge_id[number], CHAN_WEAPON, "stz/HealthArmor-Stations/ArmorRecharge.wav", 1.0, ATTN_NORM, SND_STOP, PITCH_NORM);
				emit_sound(id, CHAN_STREAM, "stz/HealthArmor-Stations/ArmorRechargeOk.wav", 1.0, ATTN_NORM, 0, PITCH_NORM);
			}
		}
	}
	else
	{
		emit_sound(g_recharge_id[number], CHAN_WEAPON, "stz/HealthArmor-Stations/ArmorRecharge.wav", 1.0, ATTN_NORM, SND_STOP, PITCH_NORM);
		emit_sound(g_recharge_id[number], CHAN_STREAM, "stz/HealthArmor-Stations/ArmorRechargeNo.wav", 1.0, ATTN_NORM, 0, PITCH_NORM);
		// Armor-Station is empty
		if(!task_exists(477434+id+number))
		{
			new param[2];
			param[0] = id;
			param[1] = number;
			// Plan a task to refresh the Armor-Station value
			set_task(g_cvar_rechargereloadtime, "reset_ArmorStation", 477434+id+number, param, 2);
		}
	}
}


//*****************************************************************************************************************
//*****************************************   F I L E H A N D L I N G   *******************************************
//*****************************************************************************************************************

//+++++ SAVE POSITION TO FILE ++++++
public save_pos()
{
	new text[256];
	
	get_configsdir(g_file_name, 255);
	format(g_file_name, 255, "%s/%s/%s.txt", g_file_name, CONFIGFOLDER, g_map_name);
	
	pev(g_entity, pev_angles, g_entity_angles);
	formatex(text, 255, "^n%s^norigin %f %f %f^nangles %f %f %f", g_models[g_curmodeltype], g_aimOrigin[2][0], g_aimOrigin[2][1], g_aimOrigin[2][2], g_entity_angles[0], g_entity_angles[1], g_entity_angles[2]);
	write_file(g_file_name, text);
	
	if(g_curmodeltype == 0)
	{
		g_medkit_coords[g_medkit_count][0] = g_aimOrigin[2][0];
		g_medkit_coords[g_medkit_count][1] = g_aimOrigin[2][1];
		g_medkit_coords[g_medkit_count][2] = g_aimOrigin[2][2];
		g_medkit_angles[g_medkit_count][0] = g_entity_angles[0];
		g_medkit_angles[g_medkit_count][1] = g_entity_angles[1];
		g_medkit_angles[g_medkit_count][2] = g_entity_angles[2];
		g_medkit_id[g_medkit_count] = g_entity;
		g_medkit_count++;
	}
	else
	{
		g_recharge_coords[g_recharge_count][0] = g_aimOrigin[2][0];
		g_recharge_coords[g_recharge_count][1] = g_aimOrigin[2][1];
		g_recharge_coords[g_recharge_count][2] = g_aimOrigin[2][2];
		g_recharge_angles[g_recharge_count][0] = g_entity_angles[0];
		g_recharge_angles[g_recharge_count][1] = g_entity_angles[1];
		g_recharge_angles[g_recharge_count][2] = g_entity_angles[2];
		g_recharge_id[g_recharge_count] = g_entity;
		g_recharge_count++;
	}	
	g_entity = 0;
	resetStations();
}

//+++++ LOAD THE SAVED Stations ++++++
load_saved_stations(file_name[])
{
	new lastread = 0;
	new file_handle = fopen(file_name, "r");
	
	if(!file_handle) return PLUGIN_HANDLED;
		
	new file_text[64];
	new ent, str_value[3][16];
	
	while(!feof(file_handle))
	{
		fgets(file_handle, file_text, 63);
		trim(file_text);
		
		if(equal(file_text, "//", 2) || !file_text[0]) continue;
		
		if(contain(file_text, "HealthStation.mdl") != -1)
		{
			if(!file_exists(file_text))
			{
				log_amx("Error: Failed to load HealthStation.mdl, model does not exist.", file_text);
				continue;
			}
			ent = engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, "info_target"));
			engfunc(EngFunc_SetModel, ent, file_text);
			set_pev(ent, pev_classname, MEDKITCLASS);
			set_pev(ent, pev_controller_0, 125);
			set_pev(ent, pev_controller_1, 125);
			set_pev(ent, pev_controller_2, 125);
			set_pev(ent, pev_controller_3, 125);
			set_pev(ent, pev_solid, 2);
			
			setGlow(ent);
			g_medkit_id[g_medkit_count] = ent;
			lastread = 1;
		}
		else if(contain(file_text, "ArmorStation.mdl") != -1)
		{
			if(!file_exists(file_text))
			{
				log_amx("Error: Failed to load ArmorStation.mdl, model does not exist.");
				continue;
			}
			ent = engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, "info_target"));
			engfunc(EngFunc_SetModel, ent, file_text);
			set_pev(ent, pev_classname, RECHARGECLASS);
			set_pev(ent, pev_controller_0, 125);
			set_pev(ent, pev_controller_1, 125);
			set_pev(ent, pev_controller_2, 125);
			set_pev(ent, pev_controller_3, 125);
			set_pev(ent, pev_solid, 2);
			
			setGlow(ent);
			g_recharge_id[g_recharge_count] = ent;
			lastread = 2;
		}
		else if(equal(file_text, "origin", 6))
		{
			parse(file_text[6], str_value[0], 15, str_value[1], 15, str_value[2], 15);
			
			switch(lastread)
			{
				case 1:
				{
					g_medkit_coords[g_medkit_count][0] = str_to_float(str_value[0]);
					g_medkit_coords[g_medkit_count][1] = str_to_float(str_value[1]);
					g_medkit_coords[g_medkit_count][2] = str_to_float(str_value[2]);
					engfunc(EngFunc_SetOrigin, ent, g_medkit_coords[g_medkit_count]);
				}
				case 2:
				{
					g_recharge_coords[g_recharge_count][0] = str_to_float(str_value[0]);
					g_recharge_coords[g_recharge_count][1] = str_to_float(str_value[1]);
					g_recharge_coords[g_recharge_count][2] = str_to_float(str_value[2]);
					engfunc(EngFunc_SetOrigin, ent, g_recharge_coords[g_recharge_count]);					
				}
			}		
		}
		else if(equal(file_text, "angles", 6))
		{
			parse(file_text[6], str_value[0], 15, str_value[1], 15, str_value[2], 15);
			
			switch(lastread)
			{
				case 1:
				{
					g_medkit_angles[g_medkit_count][0] = str_to_float(str_value[0]);
					g_medkit_angles[g_medkit_count][1] = str_to_float(str_value[1]);
					g_medkit_angles[g_medkit_count][2] = str_to_float(str_value[2]);
					set_pev(ent, pev_angles, g_medkit_angles[g_medkit_count]);
					
					new Float:mins[3] = {-2.0, -2.0, 38.0};
					new Float:maxs[3] = {2.0, 2.0, 42.0};
					engfunc(EngFunc_SetSize, ent, mins, maxs);
					g_medkit_count++;
				}
				case 2:
				{
					g_recharge_angles[g_recharge_count][0] = str_to_float(str_value[0]);
					g_recharge_angles[g_recharge_count][1] = str_to_float(str_value[1]);
					g_recharge_angles[g_recharge_count][2] = str_to_float(str_value[2]);
					set_pev(ent, pev_angles, g_recharge_angles[g_recharge_count]);
					
					new Float:mins[3] = {-2.0, -2.0, 38.0};
					new Float:maxs[3] = {2.0, 2.0, 42.0};
					engfunc(EngFunc_SetSize, ent, mins, maxs);
					g_recharge_count++;
				}
			}	
			lastread = 0;
		}
	}
	fclose(file_handle);
	resetStations();
	return PLUGIN_HANDLED;
}



delete_saved_stations(num, del_class)
{
	get_configsdir(g_file_name, 255);
	format(g_file_name, 255, "%s/%s/%s.txt", g_file_name, CONFIGFOLDER, g_map_name);
	new file_handle = fopen(g_file_name, "r");
	if(!file_handle) return PLUGIN_HANDLED;
	
	new del_medkit_num;
	new del_recharge_num;
	new file_text[64];
	new str_value[3][16];
	
	while(!feof(file_handle))
	{
		fgets(file_handle, file_text, 63);
		trim(file_text);
		
		if(equal(file_text, "//", 2) || !file_text[0]) continue;
		
		if(contain(file_text, "HealthStation.mdl") != -1)
		{
			if(del_medkit_num != num)
			{
				g_del_models[g_del_num] = 0;
				del_medkit_num++;
			}
			else if(del_class == 1)
			{
				fgets(file_handle, file_text, 63);
				fgets(file_handle, file_text, 63);
				del_medkit_num++;
			}
			else
			{
				g_del_models[g_del_num] = 0;
				del_medkit_num++;
			}
		}
		
		else if(contain(file_text, "ArmorStation.mdl") != -1)
		{
			if(del_recharge_num != num)
			{
				g_del_models[g_del_num] = 1;
				del_recharge_num++;
			}
			else if(del_class == 2)
			{
				fgets(file_handle, file_text, 63);
				fgets(file_handle, file_text, 63);
				del_recharge_num++;
			}
			else
			{
				g_del_models[g_del_num] = 1;
				del_recharge_num++;
			}
		}
		
		else if(equal(file_text, "origin", 6))
		{
			parse(file_text[6], str_value[0], 15, str_value[1], 15, str_value[2], 15);
			g_del_origins[g_del_num][0] = str_to_float(str_value[0]);
			g_del_origins[g_del_num][1] = str_to_float(str_value[1]);
			g_del_origins[g_del_num][2] = str_to_float(str_value[2]);
		}
		
		else if(equal(file_text, "angles", 6))
		{
			parse(file_text[6], str_value[0], 15, str_value[1], 15, str_value[2], 15);
			g_del_angles[g_del_num][0] = str_to_float(str_value[0]);
			g_del_angles[g_del_num][1] = str_to_float(str_value[1]);
			g_del_angles[g_del_num][2] = str_to_float(str_value[2]);
			g_del_num++;
		}
	}
	
	fclose(file_handle);
	save_stations_again();
	
	return PLUGIN_HANDLED;
}


public save_stations_again()
{
	new text[256];	
	get_configsdir(g_file_name, 255);
	format(g_file_name, 255, "%s/%s/%s.txt", g_file_name, CONFIGFOLDER, g_map_name);
	new tmpfile = fopen(g_file_name,"w");
	
	for(new i = 0; i < g_del_num; ++i)
	{
		formatex(text, 255, "^n%s^norigin %f %f %f^nangles %f %f %f^n", g_models[g_del_models[i]], g_del_origins[i][0], g_del_origins[i][1], g_del_origins[i][2], g_del_angles[i][0], g_del_angles[i][1], g_del_angles[i][2]);
		fputs(tmpfile,text);
	}
	
	fclose(tmpfile);
	resetStations();
	remove_stations();
	load_saved_stations(g_file_name);
}



//*****************************************************************************************************************
//*********************************************   P R E T H I N K  ************************************************
//*****************************************************************************************************************

public PreThink(id)
{
	//+++++ PLACING STUFF (ADMIN) +++++
	if(g_adjusting && id == g_curAdjuster)
	{
		if(g_prethink_placestepper++ > PLACESTEPFREQUENCY)
		{
			if(!is_aiming_at_sky(id))
			{
				get_aim_origin(id, g_aimOrigin[2]);
	
				if(equal_f(g_aimOrigin[1], g_aimOrigin[2]) < 3)
				{
					if(pev_valid(g_entity))
					{
						engfunc(EngFunc_SetOrigin, g_entity, g_aimOrigin[2]);
						move_station(id, 3);
						
						static Float:normal[3], Float:player_origin[3], Float:test_origin[3];
						
						normal = cross_product(diff_f(g_aimOrigin[0], g_aimOrigin[1]), diff_f(g_aimOrigin[2], g_aimOrigin[1]));
						vector_to_angle(normal, g_entity_angles);
						
						minimize_normal(normal);
						test_origin = sum_f(g_aimOrigin[2], normal);
						pev(id, pev_origin, player_origin);
						
						if(get_distance_f(player_origin, test_origin) > get_distance_f(player_origin, g_aimOrigin[2]))
						{
							set_pev(g_entity, pev_angles, g_entity_angles);
						}
					}	
				}
				if(equal_f(g_aimOrigin[1], g_aimOrigin[2]) < 2 && get_distance_f(g_aimOrigin[2], g_aimOrigin[1]) > 5.0)
				{
					g_aimOrigin[0] = g_aimOrigin[1];
					g_aimOrigin[1] = g_aimOrigin[2];
				}
				g_prethink_placestepper = 0;
			}
		}
	}
	//+++++###+++++ CHECKING STUFF (STATIONS) +++++###+++++
	new Float:gametime = get_gametime();
	if(g_nextstep[id] < gametime)		// is it time for the next check?
	{		
		//~~ Check medkit-Stationstatus ~~
		for(new m = 0; m < g_medkit_count; m++)
		{
			if(pev_valid(g_medkit_id[m]))
			{
				if(ent_distance(id, g_medkit_id[m]) < 30)
				{
					// Player is near a Health-Station
					g_faraway = false;
					if(is_in_viewcone(id, g_medkit_coords[m]))
					{
						// Player is looking at a Health-Station
						if(pev(id, pev_button) & IN_USE && pev(id, pev_health) < 100.0)
						{
							// Player is pressing USE-button near a Health-Station
							GiveHealth(id, m);
							g_snd_medkit[m][id] = true;
						}
						else if(g_snd_medkit[m][id] == true)
						{
							emit_sound(g_medkit_id[m], CHAN_WEAPON, "stz/HealthArmor-Stations/HealthRecharge.wav", 1.0, ATTN_NORM, SND_STOP, PITCH_NORM);
							g_snd_medkit[m][id] = false;
						}
					}
					else if(g_snd_medkit[m][id] == true)
					{
						emit_sound(g_medkit_id[m], CHAN_WEAPON, "stz/HealthArmor-Stations/HealthRecharge.wav", 1.0, ATTN_NORM, SND_STOP, PITCH_NORM);
						g_snd_medkit[m][id] = false;
					}
				}
				else
				{
					if(ent_distance(id, g_medkit_id[m]) > 100 && g_faraway)
					{
						g_faraway = true;
						g_snd_medkit[m][id] = false;
					}
					if(g_snd_medkit[m][id] == true) emit_sound(g_medkit_id[m], CHAN_WEAPON, "stz/HealthArmor-Stations/HealthRecharge.wav", 1.0, ATTN_NORM, SND_STOP, PITCH_NORM);
				}
			}
			else
			{
				log_amx("Error: Failure in map config! Please make a new one. (Health-Station nr: %d failed to load)",m);
			}
		}
		//~~ Check recharge-Stationstatus ~~
		for(new r = 0; r < g_recharge_count; r++)
		{
			if(pev_valid(g_recharge_id[r]))
			{
				if(ent_distance(id, g_recharge_id[r]) < 30)
				{
					// Player is near a Recharge-Station
					g_faraway = false;
					if(is_in_viewcone(id, g_recharge_coords[r]))
					{
						// Player is looking at a Recharge-Station
						if(pev(id, pev_button) & IN_USE && pev(id, pev_armorvalue < 100.0))
						{
							// Player is pressing USE-Button near a Recharge-Station
							GiveArmor(id, r);
							g_snd_recharge[r][id] = true;							
						}
						else if(g_snd_recharge[r][id] == true)
						{
							emit_sound(g_recharge_id[r], CHAN_WEAPON, "stz/HealthArmor-Stations/ArmorRecharge.wav", 1.0, ATTN_NORM, SND_STOP, PITCH_NORM);
							g_snd_recharge[r][id] = false;
						}
					}
					else if(g_snd_recharge[r][id] == true)
					{
						emit_sound(g_recharge_id[r], CHAN_WEAPON, "stz/HealthArmor-Stations/ArmorRecharge.wav", 1.0, ATTN_NORM, SND_STOP, PITCH_NORM);
						g_snd_recharge[r][id] = false;
					}
				}
				else
				{
					if(ent_distance(id, g_recharge_id[r]) > 100 && g_faraway)
					{
						g_faraway = true;
						g_snd_recharge[r][id] = false;
					}
					if(g_snd_recharge[r][id] == true) emit_sound(g_recharge_id[r], CHAN_WEAPON, "stz/HealthArmor-Stations/ArmorRecharge.wav", 1.0, ATTN_NORM, SND_STOP, PITCH_NORM);
				}
			}
			else
			{
				log_amx("Error: Failure in map config! Please make a new one. (Armor-Station nr: %d failed to load)",r);
			}	
		}
		//~~ Calculate the next Checking time ~~
		if(g_faraway) g_chargesteppfrequency = 1.0;
		else g_chargesteppfrequency = 0.2;
		g_nextstep[id] = gametime + g_chargesteppfrequency; //Add a little delay for checking
		g_faraway = true;
	}
	return FMRES_HANDLED;
}



//*****************************************************************************************************************
//*************************************************   M E N U S   *************************************************
//*****************************************************************************************************************

// Display the Selection Menu
public display_select(id)
{	
	static szMenuBody[224];
	new nKeys;
	if((g_medkit_count < MAXMEDKITS) && (g_recharge_count < MAXRECHARGES))
	{
		nKeys = (1<<9)|(1<<7)|(1<<1)|(1<<0);
		formatex(szMenuBody, 223, "Choose a type: ^n^n1. medkit^n2. recharge^n^n8. Save this Position!^n^n0. Exit");
	}
	else if((g_medkit_count < MAXMEDKITS) && (g_recharge_count == MAXRECHARGES))
	{
		nKeys = (1<<9)|(1<<7)|(1<<1)|(1<<0);
		formatex(szMenuBody, 223, "Choose a type: ^n^n1. medkit^n2. \rrecharge\w^n^n8. Save this Position!^n^n0. Exit");		
	}
	else if((g_recharge_count < MAXRECHARGES) && (g_medkit_count == MAXMEDKITS)) 
	{
		nKeys = (1<<9)|(1<<7)|(1<<1)|(1<<0);
		formatex(szMenuBody, 223, "Choose a type: ^n^n1. \rmedkit\w^n2. recharge^n^n8. Save this Position!^n^n0. Exit");		
	}
	else if((g_medkit_count == MAXMEDKITS) && (g_recharge_count == MAXRECHARGES))
	{
		nKeys = (1<<9)|(1<<7)|(1<<1)|(1<<0);
		formatex(szMenuBody, 223, "You have all available Stations placed!^n^n1. \rmedkit\w^n2. \rrecharge\w^n^n8. \rSave this Position!\w^n^n0. Exit");
	}
	show_menu(id, nKeys, szMenuBody, -1, "select_menu" );
	return;
}

// Check what Key was pressed in the Selection Menu
public action_select(id, key)
{
	switch(key)
	{
		case 0: // medkit
		{
			if(g_medkit_count < MAXMEDKITS && pev_valid(g_entity))
			{
				g_curmodeltype = 0;
				engfunc(EngFunc_SetModel, g_entity, g_models[g_curmodeltype]);
				set_pev(g_entity, pev_classname, MEDKITCLASS);
				new Float:mins[3] = {-2.0, -2.0, 38.0};
				new Float:maxs[3] = {2.0, 2.0, 42.0};
				engfunc(EngFunc_SetSize, g_entity, mins, maxs);
				setGlow(g_entity);
				display_select(id);
			}else display_select(id);
		}
		case 1: // recharge
		{
			if(g_recharge_count < MAXRECHARGES && pev_valid(g_entity))
			{
				g_curmodeltype = 1;
				engfunc(EngFunc_SetModel, g_entity, g_models[g_curmodeltype]);
				set_pev(g_entity, pev_classname, RECHARGECLASS);
				new Float:mins[3] = {-2.0, -2.0, 38.0};
				new Float:maxs[3] = {2.0, 2.0, 42.0};
				engfunc(EngFunc_SetSize, g_entity, mins, maxs);				
				setGlow(g_entity);
				display_select(id);
			}else display_select(id);
		}
		case 7:	
		{
			if((g_recharge_count < MAXRECHARGES) || (g_medkit_count < MAXMEDKITS))
			{
				display_save(id);
			}else	display_select(id);
		}
		case 9:	if(pev_valid(g_entity)) engfunc(EngFunc_RemoveEntity, g_entity);
	}
}

// Display the Save Menu
public display_save(id)
{
	show_menu(id, (1<<0)|(1<<1), "Save this Medkit/Recharger?^n^n1. Yes, save it.^n2. No, delete it.^n", -1, "save_menu");
}

// Check what Key was pressed in the Save Menu
public action_save(id, key)
{
	switch (key)
	{
		case 0: save_pos();
		case 1:
		{
			if(pev_valid(g_entity))
			{
				engfunc(EngFunc_RemoveEntity, g_entity);
			}
		}
	}
}



//*****************************************************************************************************************
//***************************************   E N T I T Y H A N D L I N G   *****************************************
//*****************************************************************************************************************

//+++++ PLACE STATION ++++++
public cmd_place_station(id)
{
	if(!(get_user_flags(id) & ADMIN_ACCESS_LEVEL))
	{
		client_print(id, print_console, "You do not have access to this command.");
		return PLUGIN_HANDLED;
	}
	g_curAdjuster = id;
	new cmd[2];
	read_argv(0, cmd, 1);
	switch(cmd[0])
	{
		case '+':
		{
			if(g_adjusting)
			{
				log_amx("Error: Someone is already placing an Medkit/Recharge");
				client_print(0, print_chat, "Error: Another user is already placing an Medkit/Recharge");
				return PLUGIN_HANDLED;
			}
			if(pev_valid(g_entity)) engfunc(EngFunc_RemoveEntity, g_entity);
			if(!pev_valid(g_entity))
			{
				if(g_medkit_count < MAXMEDKITS || g_recharge_count < MAXRECHARGES) entcreate();
				else
				{
					log_amx("Error: You have placed all available Medkits/Recharges");
					client_print(0, print_chat, "Error: You have placed all available Medkits/Recharges");
					return PLUGIN_HANDLED;
				}
			}
			g_adjusting = true;
		}
		case '-':
		{
			g_adjusting = false;
			if(pev_valid(g_entity) && g_entity != 0) display_select(id);
		}
	}
	return PLUGIN_HANDLED;
}


//+++++ DELETE STATION +++++
public del_station(id)
{
	if(!(get_user_flags(id) & ADMIN_ACCESS_LEVEL))
	{
		client_print(id, print_console, "You do not have access to this command.");
		return PLUGIN_HANDLED;
	}
	
	new ent = get_ent_in_aim_radius(id, 30.0);
	new num = get_station_num(ent);
	
	if(num == -1) return PLUGIN_HANDLED_MAIN;
	
	new class[33];
	pev(ent, pev_classname, class, 32);
	if(equal(class, MEDKITCLASS)) delete_saved_stations(num, 1);
	else delete_saved_stations(num, 2);
	return PLUGIN_CONTINUE;
}


//+++++ CREATE ENTITY ++++++
public entcreate()
{		
	if(g_medkit_count == MAXMEDKITS) g_curmodeltype = 1;
	if(g_recharge_count == MAXRECHARGES) g_curmodeltype = 0;
	
	g_entity = engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, "info_target"));
	engfunc(EngFunc_SetModel, g_entity, g_models[g_curmodeltype]);
	
	if(g_curmodeltype == 0) set_pev(g_entity, pev_classname, MEDKITCLASS);
	else set_pev(g_entity, pev_classname, RECHARGECLASS);
	
	set_pev(g_entity, pev_controller_0, 125);
	set_pev(g_entity, pev_controller_1, 125);
	set_pev(g_entity, pev_controller_2, 125);
	set_pev(g_entity, pev_controller_3, 125);
	
	new Float:mins[3] = {-2.0, -2.0, 38.0};
	new Float:maxs[3] = {2.0, 2.0, 42.0};
	engfunc(EngFunc_SetSize, g_entity, mins, maxs);
	
	set_pev(g_entity, pev_solid, 2);
	
	setGlow(g_entity);
}


//+++++ LET THE STATION GLOW +++++
setGlow(ent)
{
	if(g_cvar_gloweffect && pev_valid(ent))
	{
		new class[32];
		pev(ent, pev_classname, class, 31);
		set_pev(ent, pev_renderfx, kRenderFxHologram);
		if(equal(class, MEDKITCLASS)) set_pev(ent, pev_rendercolor, g_colors[0]); // red for the Medkit-Station
		else set_pev(ent, pev_rendercolor, g_colors[1]); // blue for the Recharge-Station

		set_pev(ent, pev_renderfx, kRenderFxGlowShell);
		set_pev(ent, pev_renderamt, 255.0);
		set_pev(ent, pev_rendermode, kRenderTransAlpha);
	}
}


//+++++ MOVE THE ENTITY ++++++
public pull_station(id)
{
	move_station(id, 1);
}

public push_station(id)
{
	move_station(id, 2);
}

public move_station(id, flag)
{
	if(!(get_user_flags(id) & ADMIN_ACCESS_LEVEL))
	{
		client_print(id, print_console, "You do not have access to this command.");
		return PLUGIN_HANDLED;
	}
	if(pev_valid(g_entity))
	{
		static Float:player_origin[3], Float:distance[3], greatest;
		pev(id, pev_origin, player_origin);
		distance[0] = abs_f(player_origin[0] - g_aimOrigin[2][0]);
		distance[1] = abs_f(player_origin[1] - g_aimOrigin[2][1]);
		distance[2] = abs_f(player_origin[2] - g_aimOrigin[2][2]);
		for(new i = 0; i < 3; i++)
		{
			if(distance[i] > distance[greatest]) greatest = i;
		}
		switch(flag)
		{
			case 1: {g_aimOrigin[2][greatest] += (player_origin[greatest] > g_aimOrigin[2][greatest] ? DISTANCE : -DISTANCE);}
			case 2: {g_aimOrigin[2][greatest] -= (player_origin[greatest] > g_aimOrigin[2][greatest] ? DISTANCE : -DISTANCE);}
			case 3: {g_aimOrigin[2][greatest] += (player_origin[greatest] > g_aimOrigin[2][greatest] ? 2.0 : -2.0);}
		}
		engfunc(EngFunc_SetOrigin, g_entity, g_aimOrigin[2]);
	}
	return 1;
}



//*****************************************************************************************************************
//************************************************   F U N C T I O N S  *******************************************
//*****************************************************************************************************************

//+++++ Taken from fakemeta_util.inc (very nice! many thanks to VEN from http://forums.alliedmods.net/index.php +++++
bool:is_in_viewcone(index, const Float:point[3])
{
	new Float:angles[3]
	pev(index, pev_angles, angles)
	engfunc(EngFunc_MakeVectors, angles)
	global_get(glb_v_forward, angles)
	angles[2] = 0.0

	new Float:origin[3], Float:diff[3], Float:norm[3]
	pev(index, pev_origin, origin)
	vec_sub(point, origin, diff)
	diff[2] = 0.0
	vec_normalize(diff, norm)

	new Float:dot, Float:fov
	dot = vec_dot(norm, angles)
	pev(index, pev_fov, fov)
	if (dot >= floatcos(fov * M_PI / 360))
		return true

	return false
}

get_aim_origin(index, Float:origin[3])
{
	static Float:start[3], Float:view_ofs[3];
	pev(index, pev_origin, start);
	pev(index, pev_view_ofs, view_ofs);
	vec_add(start, view_ofs, start);
	
	static Float:dest[3];
	pev(index, pev_v_angle, dest);
	engfunc(EngFunc_MakeVectors, dest);
	global_get(glb_v_forward, dest);
	vec_mul_scalar(dest, 9999.0, dest);
	vec_add(start, dest, dest);
	
	engfunc(EngFunc_TraceLine, start, dest, 0, index, 0);
	get_tr2(0, TR_vecEndPos, origin);
	
	return 1;
}

bool:is_aiming_at_sky(index)
{
	new target, temp;
	get_user_aiming(index,target,temp);
	if(engfunc(EngFunc_PointContents,target) == CONTENTS_SKY) return true;
	return false;
}

get_ent_in_aim_radius(index, Float:radius) 
{
	static Float:start[3], Float:view_ofs[3];
	static Float:dest[3], Float:origin[3], entclass[32];
	new ent = -1;
	
	pev(index, pev_origin, start)
	pev(index, pev_view_ofs, view_ofs)
	vec_add(start, view_ofs, start)
	pev(index, pev_v_angle, dest)
	engfunc(EngFunc_MakeVectors, dest)
	global_get(glb_v_forward, dest)
	vec_mul_scalar(dest, 9999.0, dest)
	vec_add(start, dest, dest)
	engfunc(EngFunc_TraceLine, start, dest, 0, index, 0)
	get_tr2(0, TR_vecEndPos, origin)
	while((ent = engfunc(EngFunc_FindEntityInSphere, ent, origin, radius)) != 0)
	{
		pev(ent, pev_classname, entclass, 32)
		if(equal(entclass, MEDKITCLASS) || equal(entclass, RECHARGECLASS)) return ent;
	}
	return 0
}

Float:ent_distance(ent1, ent2)
{
	new Float:mins1[3], Float:maxs1[3];
	new Float:mins2[3], Float:maxs2[3];
	new Float:dist[3];
	pev(ent1, pev_absmin, mins1);
	pev(ent1, pev_absmax, maxs1);
	pev(ent2, pev_absmin, mins2);
	pev(ent2, pev_absmax, maxs2);
	for (new i = 0; i < 3; ++i)
	{
		if (mins1[i] > maxs2[i]) dist[i] = mins1[i] - maxs2[i];
		else if (mins2[i] > maxs1[i]) dist[i] = mins2[i] - maxs1[i];
	}
	return vector_length(dist);
}

/*bool:is_visible(index, const Float:point[3], ignoremonsters = 0)
{
	new Float:start[3], Float:view_ofs[3];
	pev(index, pev_origin, start);
	pev(index, pev_view_ofs, view_ofs);
	vec_add(start, view_ofs, start);

	engfunc(EngFunc_TraceLine, start, point, ignoremonsters, index, 0);

	new Float:fraction;
	get_tr2(0, TR_flFraction, fraction);
	if (fraction == 1.0)
		return true;

	return false;
}*/

minimize_normal(Float:normal[3])
{
	normal[0] /= 10.0;
	normal[1] /= 10.0;
	normal[2] /= 10.0;
	return 1;
}

Float:abs_f(Float:x)
{
	if(x < 0) return (-1.0 * x);
	return x;
}

equal_f(Float:origin1[3], Float:origin2[3])
{
	new num_equal = (origin1[0] == origin2[0] ? 1 : 0);
	num_equal += (origin1[1] == origin2[1] ? 1 : 0);
	num_equal += (origin1[2] == origin2[2] ? 1 : 0);
	return num_equal;
}

Float:sum_f(Float:origin1[3], Float:origin2[3])
{
	new Float:result[3];
	result[0] = origin1[0] + origin2[0];
	result[1] = origin1[1] + origin2[1];
	result[2] = origin1[2] + origin2[2];
	return result;
}

Float:diff_f(Float:origin1[3], Float:origin2[3])
{
	new Float:result[3];
	result[0] = origin1[0] - origin2[0];
	result[1] = origin1[1] - origin2[1];
	result[2] = origin1[2] - origin2[2];
	return result;
}

Float:cross_product(Float:origin1[3], Float:origin2[3])
{
	new Float:result[3];
	result[0] = origin1[1]*origin2[2] - origin1[2]*origin2[1];
	result[1] = origin1[2]*origin2[0] - origin1[0]*origin2[2];
	result[2] = origin1[0]*origin2[1] - origin1[1]*origin2[0];
	return result;
}


//+++++ Taken from xs.inc (very nice! Many thanks to PM from http://forums.alliedmods.net/index.php +++++
vec_add(const Float:in1[], const Float:in2[], Float:out[])
{
	out[0] = in1[0] + in2[0];
	out[1] = in1[1] + in2[1];
	out[2] = in1[2] + in2[2];
}

vec_sub(const Float:in1[], const Float:in2[], Float:out[])
{
	out[0] = in1[0] - in2[0];
	out[1] = in1[1] - in2[1];
	out[2] = in1[2] - in2[2];
}

vec_mul_scalar(const Float:vec[], Float:scalar, Float:out[])
{
	out[0] = vec[0] * scalar;
	out[1] = vec[1] * scalar;
	out[2] = vec[2] * scalar;
}

vec_normalize(const Float:vec[], Float:out[])
{
	new Float:invlen = xs_rsqrt(vec[0]*vec[0] + vec[1]*vec[1] + vec[2]*vec[2]);
	out[0] = vec[0] * invlen;
	out[1] = vec[1] * invlen;
	out[2] = vec[2] * invlen;
}

Float:xs_rsqrt(Float:x)
{
	return 1.0 / floatsqroot(x);
}
	
Float:vec_dot(const Float:vec1[], const Float:vec2[])
{
	return vec1[0]*vec2[0] + vec1[1]*vec2[1] + vec1[2]*vec2[2];
}

get_station_num(id)
{
	for(new m = 0; m < g_medkit_count; m++)
		if(g_medkit_id[m] == id) return m;

	for(new r = 0; r < g_recharge_count; r++)
		if(g_recharge_id[r] == id) return r;

	return -1;
}

//+++++ Manipulate the user armor ++++++
set_realarmor(id, armor=2)
{
	if(is_module_loaded("cstrike") != -1)
	{
		set_pdata_int(id, OFFSET_ARMORTYPE, armor, OFFSET_LINUX);
		message_begin(MSG_ONE, g_umsgA, {0,0,0}, id);
		write_byte(1);
		message_end();
	}
}


Аватар
LoShIaA
Извън линия
Потребител
Потребител
Мнения: 323
Регистриран на: 20 Окт 2016, 14:44
Местоположение: Стара Загора
Се отблагодари: 120 пъти
Получена благодарност: 9 пъти

Health Armor Stations плъгина да не ти прави 100 кръвта, когато имаш над 100 и използваш станция

Мнение от LoShIaA » 23 Окт 2017, 09:39

При новия код пак работи само за кръвта. Бронята ми я прави отново на 100.

Аватар
OciXCrom
Извън линия
Администратор
Администратор
Мнения: 7206
Регистриран на: 06 Окт 2016, 19:20
Местоположение: /resetscore
Се отблагодари: 117 пъти
Получена благодарност: 1295 пъти
Обратна връзка:

Health Armor Stations плъгина да не ти прави 100 кръвта, когато имаш над 100 и използваш станция

Мнение от OciXCrom » 23 Окт 2017, 15:51

Объркал съм скобите.

Код за потвърждение: Избери целия код

/**********************************************************************************
* 									Health/Armor-Stations
*
*
* Author: regalis ([email protected])
*
*
*	Version: 0.3.5
*
*
*
*	Description:
*		Do you know HalfLife Deathmatch?
*		There are Stations to recharge your Health and you Armor.
*		Now you can have these Station in Counterstrike too!
*		Place the Stations you want where you want ;)
*
*		To place a Station make sure you are an admin and bind a key to "+place_station".
*		Now press the key and aim at where you want to place the station, release the key to choose which sort of station you want to place.
*		With the commands "push_station" and "pull_station" you can pull or push the station in the direction you are looking.
*		If you have choosen the station which fits your needs you can save it to the config-file which is automaticaly created for each map.
*		That all...
*		To use these Stations just stand near it and press your USE-key (standard: E)
*		The reloading of the Station is triggered as soon as the Station gets empty!
*
*
*
*
*	Admin-Commands:
*		"+place_station" - Place an Health/Armor-Station on the wall in front of you
*		"push_station" - Move the Health/Armor-Station away of you
*		"pull_station" - Move the Health/Armor-Station closer to you
*		"del_station" - Delete the Healt/Armor-Station at which you aim
*
*
*
* CVARS:
*		HA_maxhealth - How much health is in a HealthStation for everyone [number of HP](0-100) (Default: 40 HP)
*		HA_maxplayerhealth - Set the maximum amount of health a player can charge [100 - 255] (Default: 255 HP)
*		HA_healthpersec - Set the amount of HP a player get per chargecycle [1 - ?] (Default: 4 HP should be 8-12 HP per second) 
*		HA_maxarmor - How much armor is in a ArmorStation for everyone [number of AP]	(0-100)	(Default: 40 AP)
*		HA_maxplayerarmor - Set the maximum amount of armor a player can charge [100 - 255] (Default: 255 AP)
*		HA_armorpersec - Set the amount of AP a player get per chargecycle [1 - ?] (Default: 4 AP should be 8-12 AP per second)
*		HA_healthreloadtime - How long the player have to wait till he can use the same HealthStation again [number in seconds](Default: 30 sec)
*		HA_armorreloadtime - How long the player have to wait till he can use the same ArmorStation again [number in seconds]	(Default: 30 sec)
*		HA_gloweffect - Let the HealthStations glow red and the ArmorStations glow blue [0|1]	(on|off) (Default: 1)
*		
*
*
*	Requirements:
*		Fakemeta-Modul
*
*
*
*	Changelog:
*		v0.1:
*			@ initial release
*
*		v0.2:
*			! Fixed a sound bug
*			+ Added support for newly placed station giving HP/AP
*			+ Added 4 new CVARS for more customization
*
*		v0.3:
*			- Removed static declaration for global Variables
*			- Removed "stock" for functions
*			+ Added a function to delete placed stations
*			+ Added real armor to the stations (only for Counterstrike)
*		
*		v0.3.1:
*			! fixed a bug with realarmor(it is only for CounterStrike)
*
*		v0.3.5:
*			!fixed a bug when you placed a station at the sky/ceiling the server crashed...now it is handled
*
*
* Known Bugs:
*		- At some placing angles the station looks black
*			(Workaround: Just place it from another angle)
*
*
*	TODO:
*		- maybe optimizing a little
*
*
*	Credits:
*		stupok69 for his nice In-Game-Ads where i have taken the Station placing (http://forums.alliedmods.net/showthread.php?p=424583)
*		Cheap_suit for his help here: (http://forums.alliedmods.net/showpost.php?p=482976&postcount=4)
*		Alka for the help on fixing the bug with the "placing at the sky/ceiling"
*		Simon Logic for his idea with Armour-Absence-Fix Plugin here: (http://forums.alliedmods.net/showthread.php?t=55591)
*		VEN for his fakemeta_util.inc here: (http://forums.alliedmods.net/showthread.php?t=28284)
*		PM for his xs.inc
*
*
***********************************************************************************/
#include <amxmodx>
#include <amxmisc>
#include <fakemeta>


//++++++++++++++++++++
//+++++ DEFINES ++++++
//++++++++++++++++++++
// Define the offset for the Armor manipulation stock
#if cellbits == 32
	#define OFFSET_ARMORTYPE 112
#else
	#define OFFSET_ARMORTYPE 137
#endif
#define OFFSET_LINUX 5

#define CONFIGFOLDER "HA-Stations"
#define PLACESTEPFREQUENCY 10
#define DISTANCE 3.0
#define ADMIN_ACCESS_LEVEL ADMIN_BAN
#define MAXPLAYERS 32
#define MAXMEDKITS 15
#define MAXRECHARGES 15
#define MEDKITCLASS "ha_medkit"
#define RECHARGECLASS "ha_recharge"
#define SND_STOP (1<<5)

// Define the Author :P 
#define PLUGIN "Healt&Armor-Stations"
#define VERSION "0.3.5"
#define AUTHOR "regalis"


//+++++++++++++++++++++++++++++
//+++++ GLOBAL VARIABLES ++++++
//+++++++++++++++++++++++++++++
// The models
new const g_models[][] =
{
	"models/stz/HealthArmor-Stations/HealthStation.mdl",
	"models/stz/HealthArmor-Stations/ArmorStation.mdl"
}
new const gModelIndex = sizeof g_models;

// The Glow colors
new const Float:g_colors[][3] = {
	{255.0, 0.0, 0.0},
	{0.0, 0.0, 255.0}
}

// ################## FOR FUTURE USAGE #################
//new static bool:g_restart_attempt[33];
// ################## FOR FUTURE USAGE #################


//+++++ MESSAGE IDs ++++++
new g_umsgA;
//new g_msgM;
	
	
//+++++ Adminstuff + Filehandling +++++
new g_prethink_placestepper;
new g_curmodeltype;
new g_entity;
new g_curAdjuster = -1;
new Float:g_aimOrigin[3][3];
new Float:g_entity_angles[3];
new g_file_name[256]
new g_map_name[32];
new bool:g_adjusting = false;

//+++++ Deleting +++++
new g_del_num;
new g_del_models[MAXMEDKITS+MAXRECHARGES];
new Float:g_del_origins[MAXMEDKITS+MAXRECHARGES][3];
new Float:g_del_angles[MAXMEDKITS+MAXRECHARGES][3];

//+++++ Checking the usage +++++
new Float:g_nextstep[MAXPLAYERS+1];
new Float:g_chargesteppfrequency = 0.5;
new bool:g_faraway;
new g_cvar_gloweffect;

// Medkit
new Float:g_medkit_coords[MAXMEDKITS][3];
new Float:g_medkit_angles[MAXMEDKITS][3];
new g_medkit_id[MAXMEDKITS];
new g_medkit_count;

// Recharge
new Float:g_recharge_coords[MAXRECHARGES][3];
new Float:g_recharge_angles[MAXRECHARGES][3];
new g_recharge_id[MAXRECHARGES];
new g_recharge_count;


//+++++ Healthhandling +++++
new g_medkit_value[MAXMEDKITS][MAXPLAYERS+1];
new bool:g_snd_medkit[MAXMEDKITS][MAXPLAYERS+1];
new g_cvar_maxhealth;
new g_cvar_maxplayerhealth;
new g_cvar_healthpersec
new Float:g_cvar_medkitreloadtime;
new g_pHealth[MAXPLAYERS+1];


//+++++ Armorhandling +++++
new g_recharge_value[MAXRECHARGES][MAXPLAYERS+1];
new bool:g_snd_recharge[MAXRECHARGES][MAXPLAYERS+1];
new g_cvar_maxarmor;
new g_cvar_maxplayerarmor;
new g_cvar_armorpersec;
new Float:g_cvar_rechargereloadtime;
new g_pArmor[MAXPLAYERS+1];


//+++++ GLOBAL CVAR POINTER ++++++
new gcvar_maxhealth;
new gcvar_maxplayerhealth;
new gcvar_medkitreloadtime;
new gcvar_healthpersec
new gcvar_maxarmor;
new gcvar_maxplayerarmor;
new gcvar_rechargereloadtime;
new gcvar_armorpersec;
new gcvar_gloweffect;



//++++++++++++++++++++++++
//+++++ PLUGIN-INIT ++++++
//++++++++++++++++++++++++
public plugin_init()
{
	register_plugin(PLUGIN, VERSION, AUTHOR);
	register_cvar(PLUGIN, VERSION, FCVAR_SERVER);
	
	//+++++ cvar pointer ++++++
	gcvar_maxhealth = register_cvar("HA_maxhealth", "40");
	gcvar_maxplayerhealth = register_cvar("HA_maxplayerhealth", "100");
	gcvar_healthpersec = register_cvar("HA_healthpersec", "2")
	gcvar_maxarmor = register_cvar("HA_maxarmor", "40");
	gcvar_maxplayerarmor = register_cvar("HA_maxplayerarmor", "100");
	gcvar_armorpersec = register_cvar("HA_armorpersec", "2");
	gcvar_medkitreloadtime = register_cvar("HA_healthreloadtime", "20");
	gcvar_rechargereloadtime = register_cvar("HA_armorreloadtime", "20");
	gcvar_gloweffect = register_cvar("HA_gloweffect", "1");
	
	//+++++ Admin Commands +++++
	register_clcmd("+place_station", "cmd_place_station", ADMIN_ACCESS_LEVEL);
	register_clcmd("-place_station", "cmd_place_station", ADMIN_ACCESS_LEVEL);
	register_clcmd("pull_station", "pull_station", ADMIN_ACCESS_LEVEL);
	register_clcmd("push_station", "push_station", ADMIN_ACCESS_LEVEL);
	register_clcmd("del_station", "del_station", ADMIN_ACCESS_LEVEL);
	
	//+++++ Menu Commands +++++
	register_menucmd(register_menuid("save_menu"), (1<<0)|(1<<1), "action_save");
	register_menucmd(register_menuid("select_menu"), 1023, "action_select");
	
	//################## FOR FUTURE USAGE #################
	/*
	//+++++ Client Commands ++++++
	register_clcmd("fullupdate", "clcmd_fullupdate");
	//+++++ Events ++++++
	register_event("ResetHUD", "event_hud_reset", "be");
	register_event("TextMsg", "event_restart_attempt", "a", "2=#Game_will_restart_in");
	*/
	//################## FOR FUTURE USAGE #################
	
	//+++++ Message ID +++++
	g_umsgA = get_user_msgid("ArmorType");
	//g_umsgM = get_user_msgid("Money");
	
	//+++++ Logevents ++++++
	register_logevent("event_roundStart", 2, "1=Round_Start");
	register_logevent("event_round_end", 2, "1=Round_End");
	
	//+++++ Forwards +++++
	register_forward(FM_PlayerPreThink, "PreThink");
	
	//+++++ Read the Config +++++
	readCvars();
	
	//+++++ Load the saved Stations +++++
	load_saved_stations(g_file_name);
}



//++++++++++++++++++++++++++++
//+++++ PLUGIN-PRECACHE ++++++
//++++++++++++++++++++++++++++
public plugin_precache()
{
	new configs_dir[64];
	get_configsdir(configs_dir, 63);
	get_mapname(g_map_name, 31);
	
	// Save the Configfilename in a global variable
	formatex(g_file_name, 255, "%s/%s", configs_dir, CONFIGFOLDER);
	if(!dir_exists(g_file_name)) mkdir(g_file_name);
	formatex(g_file_name, 255, "%s/%s/%s.txt", configs_dir, CONFIGFOLDER, g_map_name);
	
	// Precache the models
	for(new m = 0; m < gModelIndex; m++) engfunc(EngFunc_PrecacheModel,g_models[m]);
	
	
	// Precache the sounds
	precache_sound("stz/HealthArmor-Stations/ArmorRecharge.wav");
	precache_sound("stz/HealthArmor-Stations/ArmorRechargeOk.wav");
	precache_sound("stz/HealthArmor-Stations/ArmorRechargeNo.wav");
	precache_sound("stz/HealthArmor-Stations/HealthRecharge.wav");
	precache_sound("stz/HealthArmor-Stations/HealthRechargeOk.wav");
	precache_sound("stz/HealthArmor-Stations/HealthRechargeNo.wav");
}




//*****************************************************************************************************************
//****************************************   G E N E R A L S T U F F   ********************************************
//*****************************************************************************************************************

//################## FOR FUTURE USAGE #################
/* 
//+++++ CLIENT COMMAND FULLUPDATE ++++++
public clcmd_fullupdate()
{
	return PLUGIN_HANDLED_MAIN;
}

//+++++ Event RESTART-ATTEMPT ++++++
public event_restart_attempt()
{
	new players[32], num;
	get_players(players, num, "a");
	for (new i; i < num; ++i)
	{
		g_restart_attempt[players[i]] = true;
	}
}

//+++++ Event HUD-RESET ++++++
public event_hud_reset(id)
{
	if (g_restart_attempt[id])
	{
		g_restart_attempt[id] = false;
		return;
	}
	event_player_spawn(id);
}

//+++++ Event PLAYERSPAWN ++++++
public event_player_spawn(id)
{
	// nothing to do...maybe later ;)
}
*/
//################## FOR FUTURE USAGE #################

//+++++ Event ROUNDSTART ++++++
public event_roundStart()
{
	readCvars();
	resetStations();
}

public event_round_end()
{
	resetStations();
}

//+++++ READ THE CVARS +++++++
readCvars()
{
	// Putting the CVARS in the global variables
	g_cvar_maxarmor = get_pcvar_num(gcvar_maxarmor);
	g_cvar_maxplayerarmor = get_pcvar_num(gcvar_maxplayerarmor);
	g_cvar_armorpersec = get_pcvar_num(gcvar_armorpersec);
	g_cvar_maxhealth = get_pcvar_num(gcvar_maxhealth);
	g_cvar_maxplayerhealth = get_pcvar_num(gcvar_maxplayerhealth);
	g_cvar_healthpersec = get_pcvar_num(gcvar_healthpersec);
	g_cvar_rechargereloadtime = get_pcvar_float(gcvar_rechargereloadtime);
	g_cvar_medkitreloadtime = get_pcvar_float(gcvar_medkitreloadtime);
	g_cvar_gloweffect = get_pcvar_num(gcvar_gloweffect);
}



//*****************************************************************************************************************
//*****************************************   S T A T I O N H A N D L I N G   *************************************
//*****************************************************************************************************************

//+++++ RESET THE STATIONS +++++++
resetStations()
{
	for (new i=0; i < 32; i++)
	{
		// Reset medkit-Stations to the cvar value
		for(new m = 0; m < g_medkit_count; m++)
		{
			if(task_exists(434774+i+m))	 remove_task(434774+i+m);
			g_medkit_value[m][i] = g_cvar_maxhealth;
			if(g_snd_medkit[m][i])
			{
				emit_sound(g_medkit_id[m], CHAN_WEAPON, "stz/HealthArmor-Stations/HealthRecharge.wav", 1.0, ATTN_NORM, SND_STOP, PITCH_NORM);
				g_snd_medkit[m][i] = false;
			}
		}
		
		// Reset recharge-Stations to the cvar value
		for(new r = 0; r < g_recharge_count; r++)
		{
			if(task_exists(477434+i+r))	 remove_task(477434+i+r);
			g_recharge_value[r][i] = g_cvar_maxarmor;
			if(g_snd_recharge[r][i])
			{
				emit_sound(g_recharge_id[r], CHAN_WEAPON, "stz/HealthArmor-Stations/ArmorRecharge.wav", 1.0, ATTN_NORM, SND_STOP, PITCH_NORM);
				g_snd_recharge[r][i] = false;
			}
		}
	}
}


//+++++ RESET A HEALTH STATION +++++
public reset_HealthStation(param[2])
{
	// Get the params
	new id = param[0];
	new number = param[1];
	
	// Reset the value of the certain Station to the value stored in the cvar
	g_medkit_value[number][id] = g_cvar_maxhealth;
}


//+++++ RESET A ARMOR STATION +++++
public reset_ArmorStation(param[2])
{
	// Get the params
	new id = param[0];
	new number = param[1];
	
	// Reset the value of the certain Station to the value stored in the cvar
	g_recharge_value[number][id] = g_cvar_maxarmor;
}


remove_stations()
{
	new ent = -1;
	while((ent = engfunc(EngFunc_FindEntityByString, -1, "classname", MEDKITCLASS)) != 0)
	{
		if(pev_valid(ent))
		{
			engfunc(EngFunc_RemoveEntity, ent);
		}
	}
	ent = -1;
	while((ent = engfunc(EngFunc_FindEntityByString, -1, "classname", RECHARGECLASS)) != 0)
	{
		if(pev_valid(ent))
		{
			engfunc(EngFunc_RemoveEntity, ent);
		}
	}
	g_del_num = 0;
	g_medkit_count = 0;
	g_recharge_count = 0;
}


//*****************************************************************************************************************
//********************************   H E A L T H - A R M O R H A N D L I N G  *************************************
//*****************************************************************************************************************

//+++++ Give the player health +++++
GiveHealth(id, number)
{
	if(g_medkit_value[number][id] > 0)
	{
		// The HealthValue in the current station for this player is more than 0
		g_pHealth[id] = pev(id, pev_health); // Get the player health
		if(g_pHealth[id] <= g_cvar_maxplayerhealth-g_cvar_healthpersec)
		{
			g_medkit_value[number][id] -= g_cvar_healthpersec; // subtract the given Healthvalue from the Health-Station value
			set_pev(id, pev_health, float(g_pHealth[id]+g_cvar_healthpersec)); // Give the player the Health
			if(!g_snd_medkit[number][id])
			{
				emit_sound(g_medkit_id[number], CHAN_WEAPON, "stz/HealthArmor-Stations/HealthRecharge.wav", 1.0, ATTN_NORM, 0, PITCH_NORM);
			}
		}
		else
		{
			if(g_pHealth[id] == g_cvar_maxplayerhealth)
			{
				emit_sound(g_medkit_id[number], CHAN_WEAPON, "stz/HealthArmor-Stations/HealthRecharge.wav", 1.0, ATTN_NORM, SND_STOP, PITCH_NORM);
				emit_sound(g_medkit_id[number], CHAN_STREAM, "stz/HealthArmor-Stations/HealthRechargeNo.wav", 1.0, ATTN_NORM, 0, PITCH_NORM);
			}
			else
			{
				set_pev(id, pev_health, float(g_cvar_maxplayerhealth));
				emit_sound(g_medkit_id[number], CHAN_WEAPON, "stz/HealthArmor-Stations/HealthRecharge.wav", 1.0, ATTN_NORM, SND_STOP, PITCH_NORM);
				emit_sound(id, CHAN_STREAM, "stz/HealthArmor-Stations/HealthRechargeOk.wav", 1.0, ATTN_NORM, 0, PITCH_NORM);
			}
		}
	}
	else
	{
		emit_sound(g_medkit_id[number], CHAN_WEAPON, "stz/HealthArmor-Stations/HealthRecharge.wav", 1.0, ATTN_NORM, SND_STOP, PITCH_NORM);
		emit_sound(g_medkit_id[number], CHAN_STREAM, "stz/HealthArmor-Stations/HealthRechargeNo.wav", 1.0, ATTN_NORM, 0, PITCH_NORM);
		// Health-Station is empty
		if(!task_exists(434774+id+number))
		{
			new param[2];
			param[0] = id;
			param[1] = number;
			// Plan a task to refresh the Health-Station value
			set_task(g_cvar_medkitreloadtime, "reset_HealthStation", 434774+id+number, param, 2);
		}
	}
}

//+++++ Give the player armor +++++
GiveArmor(id, number)
{
	if(g_recharge_value[number][id] > 0)
	{
		// The ArmorValue in the current station for this player is more than 0
		g_pArmor[id] = pev(id, pev_armorvalue); // Get the player armor
		if(g_pArmor[id] <= g_cvar_maxplayerarmor-g_cvar_armorpersec)
		{
			// Player have a lower ArmorValue than 100
			g_recharge_value[number][id] -= g_cvar_armorpersec;	// Subtract the given armor from the Armor-Station value
			if(!get_pdata_int(id, OFFSET_ARMORTYPE, OFFSET_LINUX)) set_realarmor(id);
			set_pev(id, pev_armorvalue, float(g_pArmor[id]+g_cvar_armorpersec)); // Give the player the Armor
			
			if(!g_snd_recharge[number][id])
			{
				emit_sound(g_recharge_id[number], CHAN_WEAPON, "stz/HealthArmor-Stations/ArmorRecharge.wav", 1.0, ATTN_NORM, 0, PITCH_NORM);
			}
		}
		else
		{
			if(g_pArmor[id] == g_cvar_maxplayerarmor)
			{
				emit_sound(g_recharge_id[number], CHAN_WEAPON, "stz/HealthArmor-Stations/ArmorRecharge.wav", 1.0, ATTN_NORM, SND_STOP, PITCH_NORM);
				emit_sound(g_recharge_id[number], CHAN_STREAM, "stz/HealthArmor-Stations/ArmorRechargeNo.wav", 1.0, ATTN_NORM, 0, PITCH_NORM);
			}
			else
			{
				set_pev(id, pev_armorvalue, float(g_cvar_maxplayerarmor)); // If player have between 96-100 Armor set it to 100
				emit_sound(g_recharge_id[number], CHAN_WEAPON, "stz/HealthArmor-Stations/ArmorRecharge.wav", 1.0, ATTN_NORM, SND_STOP, PITCH_NORM);
				emit_sound(id, CHAN_STREAM, "stz/HealthArmor-Stations/ArmorRechargeOk.wav", 1.0, ATTN_NORM, 0, PITCH_NORM);
			}
		}
	}
	else
	{
		emit_sound(g_recharge_id[number], CHAN_WEAPON, "stz/HealthArmor-Stations/ArmorRecharge.wav", 1.0, ATTN_NORM, SND_STOP, PITCH_NORM);
		emit_sound(g_recharge_id[number], CHAN_STREAM, "stz/HealthArmor-Stations/ArmorRechargeNo.wav", 1.0, ATTN_NORM, 0, PITCH_NORM);
		// Armor-Station is empty
		if(!task_exists(477434+id+number))
		{
			new param[2];
			param[0] = id;
			param[1] = number;
			// Plan a task to refresh the Armor-Station value
			set_task(g_cvar_rechargereloadtime, "reset_ArmorStation", 477434+id+number, param, 2);
		}
	}
}


//*****************************************************************************************************************
//*****************************************   F I L E H A N D L I N G   *******************************************
//*****************************************************************************************************************

//+++++ SAVE POSITION TO FILE ++++++
public save_pos()
{
	new text[256];
	
	get_configsdir(g_file_name, 255);
	format(g_file_name, 255, "%s/%s/%s.txt", g_file_name, CONFIGFOLDER, g_map_name);
	
	pev(g_entity, pev_angles, g_entity_angles);
	formatex(text, 255, "^n%s^norigin %f %f %f^nangles %f %f %f", g_models[g_curmodeltype], g_aimOrigin[2][0], g_aimOrigin[2][1], g_aimOrigin[2][2], g_entity_angles[0], g_entity_angles[1], g_entity_angles[2]);
	write_file(g_file_name, text);
	
	if(g_curmodeltype == 0)
	{
		g_medkit_coords[g_medkit_count][0] = g_aimOrigin[2][0];
		g_medkit_coords[g_medkit_count][1] = g_aimOrigin[2][1];
		g_medkit_coords[g_medkit_count][2] = g_aimOrigin[2][2];
		g_medkit_angles[g_medkit_count][0] = g_entity_angles[0];
		g_medkit_angles[g_medkit_count][1] = g_entity_angles[1];
		g_medkit_angles[g_medkit_count][2] = g_entity_angles[2];
		g_medkit_id[g_medkit_count] = g_entity;
		g_medkit_count++;
	}
	else
	{
		g_recharge_coords[g_recharge_count][0] = g_aimOrigin[2][0];
		g_recharge_coords[g_recharge_count][1] = g_aimOrigin[2][1];
		g_recharge_coords[g_recharge_count][2] = g_aimOrigin[2][2];
		g_recharge_angles[g_recharge_count][0] = g_entity_angles[0];
		g_recharge_angles[g_recharge_count][1] = g_entity_angles[1];
		g_recharge_angles[g_recharge_count][2] = g_entity_angles[2];
		g_recharge_id[g_recharge_count] = g_entity;
		g_recharge_count++;
	}	
	g_entity = 0;
	resetStations();
}

//+++++ LOAD THE SAVED Stations ++++++
load_saved_stations(file_name[])
{
	new lastread = 0;
	new file_handle = fopen(file_name, "r");
	
	if(!file_handle) return PLUGIN_HANDLED;
		
	new file_text[64];
	new ent, str_value[3][16];
	
	while(!feof(file_handle))
	{
		fgets(file_handle, file_text, 63);
		trim(file_text);
		
		if(equal(file_text, "//", 2) || !file_text[0]) continue;
		
		if(contain(file_text, "HealthStation.mdl") != -1)
		{
			if(!file_exists(file_text))
			{
				log_amx("Error: Failed to load HealthStation.mdl, model does not exist.", file_text);
				continue;
			}
			ent = engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, "info_target"));
			engfunc(EngFunc_SetModel, ent, file_text);
			set_pev(ent, pev_classname, MEDKITCLASS);
			set_pev(ent, pev_controller_0, 125);
			set_pev(ent, pev_controller_1, 125);
			set_pev(ent, pev_controller_2, 125);
			set_pev(ent, pev_controller_3, 125);
			set_pev(ent, pev_solid, 2);
			
			setGlow(ent);
			g_medkit_id[g_medkit_count] = ent;
			lastread = 1;
		}
		else if(contain(file_text, "ArmorStation.mdl") != -1)
		{
			if(!file_exists(file_text))
			{
				log_amx("Error: Failed to load ArmorStation.mdl, model does not exist.");
				continue;
			}
			ent = engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, "info_target"));
			engfunc(EngFunc_SetModel, ent, file_text);
			set_pev(ent, pev_classname, RECHARGECLASS);
			set_pev(ent, pev_controller_0, 125);
			set_pev(ent, pev_controller_1, 125);
			set_pev(ent, pev_controller_2, 125);
			set_pev(ent, pev_controller_3, 125);
			set_pev(ent, pev_solid, 2);
			
			setGlow(ent);
			g_recharge_id[g_recharge_count] = ent;
			lastread = 2;
		}
		else if(equal(file_text, "origin", 6))
		{
			parse(file_text[6], str_value[0], 15, str_value[1], 15, str_value[2], 15);
			
			switch(lastread)
			{
				case 1:
				{
					g_medkit_coords[g_medkit_count][0] = str_to_float(str_value[0]);
					g_medkit_coords[g_medkit_count][1] = str_to_float(str_value[1]);
					g_medkit_coords[g_medkit_count][2] = str_to_float(str_value[2]);
					engfunc(EngFunc_SetOrigin, ent, g_medkit_coords[g_medkit_count]);
				}
				case 2:
				{
					g_recharge_coords[g_recharge_count][0] = str_to_float(str_value[0]);
					g_recharge_coords[g_recharge_count][1] = str_to_float(str_value[1]);
					g_recharge_coords[g_recharge_count][2] = str_to_float(str_value[2]);
					engfunc(EngFunc_SetOrigin, ent, g_recharge_coords[g_recharge_count]);					
				}
			}		
		}
		else if(equal(file_text, "angles", 6))
		{
			parse(file_text[6], str_value[0], 15, str_value[1], 15, str_value[2], 15);
			
			switch(lastread)
			{
				case 1:
				{
					g_medkit_angles[g_medkit_count][0] = str_to_float(str_value[0]);
					g_medkit_angles[g_medkit_count][1] = str_to_float(str_value[1]);
					g_medkit_angles[g_medkit_count][2] = str_to_float(str_value[2]);
					set_pev(ent, pev_angles, g_medkit_angles[g_medkit_count]);
					
					new Float:mins[3] = {-2.0, -2.0, 38.0};
					new Float:maxs[3] = {2.0, 2.0, 42.0};
					engfunc(EngFunc_SetSize, ent, mins, maxs);
					g_medkit_count++;
				}
				case 2:
				{
					g_recharge_angles[g_recharge_count][0] = str_to_float(str_value[0]);
					g_recharge_angles[g_recharge_count][1] = str_to_float(str_value[1]);
					g_recharge_angles[g_recharge_count][2] = str_to_float(str_value[2]);
					set_pev(ent, pev_angles, g_recharge_angles[g_recharge_count]);
					
					new Float:mins[3] = {-2.0, -2.0, 38.0};
					new Float:maxs[3] = {2.0, 2.0, 42.0};
					engfunc(EngFunc_SetSize, ent, mins, maxs);
					g_recharge_count++;
				}
			}	
			lastread = 0;
		}
	}
	fclose(file_handle);
	resetStations();
	return PLUGIN_HANDLED;
}



delete_saved_stations(num, del_class)
{
	get_configsdir(g_file_name, 255);
	format(g_file_name, 255, "%s/%s/%s.txt", g_file_name, CONFIGFOLDER, g_map_name);
	new file_handle = fopen(g_file_name, "r");
	if(!file_handle) return PLUGIN_HANDLED;
	
	new del_medkit_num;
	new del_recharge_num;
	new file_text[64];
	new str_value[3][16];
	
	while(!feof(file_handle))
	{
		fgets(file_handle, file_text, 63);
		trim(file_text);
		
		if(equal(file_text, "//", 2) || !file_text[0]) continue;
		
		if(contain(file_text, "HealthStation.mdl") != -1)
		{
			if(del_medkit_num != num)
			{
				g_del_models[g_del_num] = 0;
				del_medkit_num++;
			}
			else if(del_class == 1)
			{
				fgets(file_handle, file_text, 63);
				fgets(file_handle, file_text, 63);
				del_medkit_num++;
			}
			else
			{
				g_del_models[g_del_num] = 0;
				del_medkit_num++;
			}
		}
		
		else if(contain(file_text, "ArmorStation.mdl") != -1)
		{
			if(del_recharge_num != num)
			{
				g_del_models[g_del_num] = 1;
				del_recharge_num++;
			}
			else if(del_class == 2)
			{
				fgets(file_handle, file_text, 63);
				fgets(file_handle, file_text, 63);
				del_recharge_num++;
			}
			else
			{
				g_del_models[g_del_num] = 1;
				del_recharge_num++;
			}
		}
		
		else if(equal(file_text, "origin", 6))
		{
			parse(file_text[6], str_value[0], 15, str_value[1], 15, str_value[2], 15);
			g_del_origins[g_del_num][0] = str_to_float(str_value[0]);
			g_del_origins[g_del_num][1] = str_to_float(str_value[1]);
			g_del_origins[g_del_num][2] = str_to_float(str_value[2]);
		}
		
		else if(equal(file_text, "angles", 6))
		{
			parse(file_text[6], str_value[0], 15, str_value[1], 15, str_value[2], 15);
			g_del_angles[g_del_num][0] = str_to_float(str_value[0]);
			g_del_angles[g_del_num][1] = str_to_float(str_value[1]);
			g_del_angles[g_del_num][2] = str_to_float(str_value[2]);
			g_del_num++;
		}
	}
	
	fclose(file_handle);
	save_stations_again();
	
	return PLUGIN_HANDLED;
}


public save_stations_again()
{
	new text[256];	
	get_configsdir(g_file_name, 255);
	format(g_file_name, 255, "%s/%s/%s.txt", g_file_name, CONFIGFOLDER, g_map_name);
	new tmpfile = fopen(g_file_name,"w");
	
	for(new i = 0; i < g_del_num; ++i)
	{
		formatex(text, 255, "^n%s^norigin %f %f %f^nangles %f %f %f^n", g_models[g_del_models[i]], g_del_origins[i][0], g_del_origins[i][1], g_del_origins[i][2], g_del_angles[i][0], g_del_angles[i][1], g_del_angles[i][2]);
		fputs(tmpfile,text);
	}
	
	fclose(tmpfile);
	resetStations();
	remove_stations();
	load_saved_stations(g_file_name);
}



//*****************************************************************************************************************
//*********************************************   P R E T H I N K  ************************************************
//*****************************************************************************************************************

public PreThink(id)
{
	//+++++ PLACING STUFF (ADMIN) +++++
	if(g_adjusting && id == g_curAdjuster)
	{
		if(g_prethink_placestepper++ > PLACESTEPFREQUENCY)
		{
			if(!is_aiming_at_sky(id))
			{
				get_aim_origin(id, g_aimOrigin[2]);
	
				if(equal_f(g_aimOrigin[1], g_aimOrigin[2]) < 3)
				{
					if(pev_valid(g_entity))
					{
						engfunc(EngFunc_SetOrigin, g_entity, g_aimOrigin[2]);
						move_station(id, 3);
						
						static Float:normal[3], Float:player_origin[3], Float:test_origin[3];
						
						normal = cross_product(diff_f(g_aimOrigin[0], g_aimOrigin[1]), diff_f(g_aimOrigin[2], g_aimOrigin[1]));
						vector_to_angle(normal, g_entity_angles);
						
						minimize_normal(normal);
						test_origin = sum_f(g_aimOrigin[2], normal);
						pev(id, pev_origin, player_origin);
						
						if(get_distance_f(player_origin, test_origin) > get_distance_f(player_origin, g_aimOrigin[2]))
						{
							set_pev(g_entity, pev_angles, g_entity_angles);
						}
					}	
				}
				if(equal_f(g_aimOrigin[1], g_aimOrigin[2]) < 2 && get_distance_f(g_aimOrigin[2], g_aimOrigin[1]) > 5.0)
				{
					g_aimOrigin[0] = g_aimOrigin[1];
					g_aimOrigin[1] = g_aimOrigin[2];
				}
				g_prethink_placestepper = 0;
			}
		}
	}
	//+++++###+++++ CHECKING STUFF (STATIONS) +++++###+++++
	new Float:gametime = get_gametime();
	if(g_nextstep[id] < gametime)		// is it time for the next check?
	{		
		//~~ Check medkit-Stationstatus ~~
		for(new m = 0; m < g_medkit_count; m++)
		{
			if(pev_valid(g_medkit_id[m]))
			{
				if(ent_distance(id, g_medkit_id[m]) < 30)
				{
					// Player is near a Health-Station
					g_faraway = false;
					if(is_in_viewcone(id, g_medkit_coords[m]))
					{
						// Player is looking at a Health-Station
						if(pev(id, pev_button) & IN_USE && pev(id, pev_health) < 100.0)
						{
							// Player is pressing USE-button near a Health-Station
							GiveHealth(id, m);
							g_snd_medkit[m][id] = true;
						}
						else if(g_snd_medkit[m][id] == true)
						{
							emit_sound(g_medkit_id[m], CHAN_WEAPON, "stz/HealthArmor-Stations/HealthRecharge.wav", 1.0, ATTN_NORM, SND_STOP, PITCH_NORM);
							g_snd_medkit[m][id] = false;
						}
					}
					else if(g_snd_medkit[m][id] == true)
					{
						emit_sound(g_medkit_id[m], CHAN_WEAPON, "stz/HealthArmor-Stations/HealthRecharge.wav", 1.0, ATTN_NORM, SND_STOP, PITCH_NORM);
						g_snd_medkit[m][id] = false;
					}
				}
				else
				{
					if(ent_distance(id, g_medkit_id[m]) > 100 && g_faraway)
					{
						g_faraway = true;
						g_snd_medkit[m][id] = false;
					}
					if(g_snd_medkit[m][id] == true) emit_sound(g_medkit_id[m], CHAN_WEAPON, "stz/HealthArmor-Stations/HealthRecharge.wav", 1.0, ATTN_NORM, SND_STOP, PITCH_NORM);
				}
			}
			else
			{
				log_amx("Error: Failure in map config! Please make a new one. (Health-Station nr: %d failed to load)",m);
			}
		}
		//~~ Check recharge-Stationstatus ~~
		for(new r = 0; r < g_recharge_count; r++)
		{
			if(pev_valid(g_recharge_id[r]))
			{
				if(ent_distance(id, g_recharge_id[r]) < 30)
				{
					// Player is near a Recharge-Station
					g_faraway = false;
					if(is_in_viewcone(id, g_recharge_coords[r]))
					{
						// Player is looking at a Recharge-Station
						if(pev(id, pev_button) & IN_USE && pev(id, pev_armorvalue) < 100.0)
						{
							// Player is pressing USE-Button near a Recharge-Station
							GiveArmor(id, r);
							g_snd_recharge[r][id] = true;							
						}
						else if(g_snd_recharge[r][id] == true)
						{
							emit_sound(g_recharge_id[r], CHAN_WEAPON, "stz/HealthArmor-Stations/ArmorRecharge.wav", 1.0, ATTN_NORM, SND_STOP, PITCH_NORM);
							g_snd_recharge[r][id] = false;
						}
					}
					else if(g_snd_recharge[r][id] == true)
					{
						emit_sound(g_recharge_id[r], CHAN_WEAPON, "stz/HealthArmor-Stations/ArmorRecharge.wav", 1.0, ATTN_NORM, SND_STOP, PITCH_NORM);
						g_snd_recharge[r][id] = false;
					}
				}
				else
				{
					if(ent_distance(id, g_recharge_id[r]) > 100 && g_faraway)
					{
						g_faraway = true;
						g_snd_recharge[r][id] = false;
					}
					if(g_snd_recharge[r][id] == true) emit_sound(g_recharge_id[r], CHAN_WEAPON, "stz/HealthArmor-Stations/ArmorRecharge.wav", 1.0, ATTN_NORM, SND_STOP, PITCH_NORM);
				}
			}
			else
			{
				log_amx("Error: Failure in map config! Please make a new one. (Armor-Station nr: %d failed to load)",r);
			}	
		}
		//~~ Calculate the next Checking time ~~
		if(g_faraway) g_chargesteppfrequency = 1.0;
		else g_chargesteppfrequency = 0.2;
		g_nextstep[id] = gametime + g_chargesteppfrequency; //Add a little delay for checking
		g_faraway = true;
	}
	return FMRES_HANDLED;
}



//*****************************************************************************************************************
//*************************************************   M E N U S   *************************************************
//*****************************************************************************************************************

// Display the Selection Menu
public display_select(id)
{	
	static szMenuBody[224];
	new nKeys;
	if((g_medkit_count < MAXMEDKITS) && (g_recharge_count < MAXRECHARGES))
	{
		nKeys = (1<<9)|(1<<7)|(1<<1)|(1<<0);
		formatex(szMenuBody, 223, "Choose a type: ^n^n1. medkit^n2. recharge^n^n8. Save this Position!^n^n0. Exit");
	}
	else if((g_medkit_count < MAXMEDKITS) && (g_recharge_count == MAXRECHARGES))
	{
		nKeys = (1<<9)|(1<<7)|(1<<1)|(1<<0);
		formatex(szMenuBody, 223, "Choose a type: ^n^n1. medkit^n2. \rrecharge\w^n^n8. Save this Position!^n^n0. Exit");		
	}
	else if((g_recharge_count < MAXRECHARGES) && (g_medkit_count == MAXMEDKITS)) 
	{
		nKeys = (1<<9)|(1<<7)|(1<<1)|(1<<0);
		formatex(szMenuBody, 223, "Choose a type: ^n^n1. \rmedkit\w^n2. recharge^n^n8. Save this Position!^n^n0. Exit");		
	}
	else if((g_medkit_count == MAXMEDKITS) && (g_recharge_count == MAXRECHARGES))
	{
		nKeys = (1<<9)|(1<<7)|(1<<1)|(1<<0);
		formatex(szMenuBody, 223, "You have all available Stations placed!^n^n1. \rmedkit\w^n2. \rrecharge\w^n^n8. \rSave this Position!\w^n^n0. Exit");
	}
	show_menu(id, nKeys, szMenuBody, -1, "select_menu" );
	return;
}

// Check what Key was pressed in the Selection Menu
public action_select(id, key)
{
	switch(key)
	{
		case 0: // medkit
		{
			if(g_medkit_count < MAXMEDKITS && pev_valid(g_entity))
			{
				g_curmodeltype = 0;
				engfunc(EngFunc_SetModel, g_entity, g_models[g_curmodeltype]);
				set_pev(g_entity, pev_classname, MEDKITCLASS);
				new Float:mins[3] = {-2.0, -2.0, 38.0};
				new Float:maxs[3] = {2.0, 2.0, 42.0};
				engfunc(EngFunc_SetSize, g_entity, mins, maxs);
				setGlow(g_entity);
				display_select(id);
			}else display_select(id);
		}
		case 1: // recharge
		{
			if(g_recharge_count < MAXRECHARGES && pev_valid(g_entity))
			{
				g_curmodeltype = 1;
				engfunc(EngFunc_SetModel, g_entity, g_models[g_curmodeltype]);
				set_pev(g_entity, pev_classname, RECHARGECLASS);
				new Float:mins[3] = {-2.0, -2.0, 38.0};
				new Float:maxs[3] = {2.0, 2.0, 42.0};
				engfunc(EngFunc_SetSize, g_entity, mins, maxs);				
				setGlow(g_entity);
				display_select(id);
			}else display_select(id);
		}
		case 7:	
		{
			if((g_recharge_count < MAXRECHARGES) || (g_medkit_count < MAXMEDKITS))
			{
				display_save(id);
			}else	display_select(id);
		}
		case 9:	if(pev_valid(g_entity)) engfunc(EngFunc_RemoveEntity, g_entity);
	}
}

// Display the Save Menu
public display_save(id)
{
	show_menu(id, (1<<0)|(1<<1), "Save this Medkit/Recharger?^n^n1. Yes, save it.^n2. No, delete it.^n", -1, "save_menu");
}

// Check what Key was pressed in the Save Menu
public action_save(id, key)
{
	switch (key)
	{
		case 0: save_pos();
		case 1:
		{
			if(pev_valid(g_entity))
			{
				engfunc(EngFunc_RemoveEntity, g_entity);
			}
		}
	}
}



//*****************************************************************************************************************
//***************************************   E N T I T Y H A N D L I N G   *****************************************
//*****************************************************************************************************************

//+++++ PLACE STATION ++++++
public cmd_place_station(id)
{
	if(!(get_user_flags(id) & ADMIN_ACCESS_LEVEL))
	{
		client_print(id, print_console, "You do not have access to this command.");
		return PLUGIN_HANDLED;
	}
	g_curAdjuster = id;
	new cmd[2];
	read_argv(0, cmd, 1);
	switch(cmd[0])
	{
		case '+':
		{
			if(g_adjusting)
			{
				log_amx("Error: Someone is already placing an Medkit/Recharge");
				client_print(0, print_chat, "Error: Another user is already placing an Medkit/Recharge");
				return PLUGIN_HANDLED;
			}
			if(pev_valid(g_entity)) engfunc(EngFunc_RemoveEntity, g_entity);
			if(!pev_valid(g_entity))
			{
				if(g_medkit_count < MAXMEDKITS || g_recharge_count < MAXRECHARGES) entcreate();
				else
				{
					log_amx("Error: You have placed all available Medkits/Recharges");
					client_print(0, print_chat, "Error: You have placed all available Medkits/Recharges");
					return PLUGIN_HANDLED;
				}
			}
			g_adjusting = true;
		}
		case '-':
		{
			g_adjusting = false;
			if(pev_valid(g_entity) && g_entity != 0) display_select(id);
		}
	}
	return PLUGIN_HANDLED;
}


//+++++ DELETE STATION +++++
public del_station(id)
{
	if(!(get_user_flags(id) & ADMIN_ACCESS_LEVEL))
	{
		client_print(id, print_console, "You do not have access to this command.");
		return PLUGIN_HANDLED;
	}
	
	new ent = get_ent_in_aim_radius(id, 30.0);
	new num = get_station_num(ent);
	
	if(num == -1) return PLUGIN_HANDLED_MAIN;
	
	new class[33];
	pev(ent, pev_classname, class, 32);
	if(equal(class, MEDKITCLASS)) delete_saved_stations(num, 1);
	else delete_saved_stations(num, 2);
	return PLUGIN_CONTINUE;
}


//+++++ CREATE ENTITY ++++++
public entcreate()
{		
	if(g_medkit_count == MAXMEDKITS) g_curmodeltype = 1;
	if(g_recharge_count == MAXRECHARGES) g_curmodeltype = 0;
	
	g_entity = engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, "info_target"));
	engfunc(EngFunc_SetModel, g_entity, g_models[g_curmodeltype]);
	
	if(g_curmodeltype == 0) set_pev(g_entity, pev_classname, MEDKITCLASS);
	else set_pev(g_entity, pev_classname, RECHARGECLASS);
	
	set_pev(g_entity, pev_controller_0, 125);
	set_pev(g_entity, pev_controller_1, 125);
	set_pev(g_entity, pev_controller_2, 125);
	set_pev(g_entity, pev_controller_3, 125);
	
	new Float:mins[3] = {-2.0, -2.0, 38.0};
	new Float:maxs[3] = {2.0, 2.0, 42.0};
	engfunc(EngFunc_SetSize, g_entity, mins, maxs);
	
	set_pev(g_entity, pev_solid, 2);
	
	setGlow(g_entity);
}


//+++++ LET THE STATION GLOW +++++
setGlow(ent)
{
	if(g_cvar_gloweffect && pev_valid(ent))
	{
		new class[32];
		pev(ent, pev_classname, class, 31);
		set_pev(ent, pev_renderfx, kRenderFxHologram);
		if(equal(class, MEDKITCLASS)) set_pev(ent, pev_rendercolor, g_colors[0]); // red for the Medkit-Station
		else set_pev(ent, pev_rendercolor, g_colors[1]); // blue for the Recharge-Station

		set_pev(ent, pev_renderfx, kRenderFxGlowShell);
		set_pev(ent, pev_renderamt, 255.0);
		set_pev(ent, pev_rendermode, kRenderTransAlpha);
	}
}


//+++++ MOVE THE ENTITY ++++++
public pull_station(id)
{
	move_station(id, 1);
}

public push_station(id)
{
	move_station(id, 2);
}

public move_station(id, flag)
{
	if(!(get_user_flags(id) & ADMIN_ACCESS_LEVEL))
	{
		client_print(id, print_console, "You do not have access to this command.");
		return PLUGIN_HANDLED;
	}
	if(pev_valid(g_entity))
	{
		static Float:player_origin[3], Float:distance[3], greatest;
		pev(id, pev_origin, player_origin);
		distance[0] = abs_f(player_origin[0] - g_aimOrigin[2][0]);
		distance[1] = abs_f(player_origin[1] - g_aimOrigin[2][1]);
		distance[2] = abs_f(player_origin[2] - g_aimOrigin[2][2]);
		for(new i = 0; i < 3; i++)
		{
			if(distance[i] > distance[greatest]) greatest = i;
		}
		switch(flag)
		{
			case 1: {g_aimOrigin[2][greatest] += (player_origin[greatest] > g_aimOrigin[2][greatest] ? DISTANCE : -DISTANCE);}
			case 2: {g_aimOrigin[2][greatest] -= (player_origin[greatest] > g_aimOrigin[2][greatest] ? DISTANCE : -DISTANCE);}
			case 3: {g_aimOrigin[2][greatest] += (player_origin[greatest] > g_aimOrigin[2][greatest] ? 2.0 : -2.0);}
		}
		engfunc(EngFunc_SetOrigin, g_entity, g_aimOrigin[2]);
	}
	return 1;
}



//*****************************************************************************************************************
//************************************************   F U N C T I O N S  *******************************************
//*****************************************************************************************************************

//+++++ Taken from fakemeta_util.inc (very nice! many thanks to VEN from http://forums.alliedmods.net/index.php +++++
bool:is_in_viewcone(index, const Float:point[3])
{
	new Float:angles[3]
	pev(index, pev_angles, angles)
	engfunc(EngFunc_MakeVectors, angles)
	global_get(glb_v_forward, angles)
	angles[2] = 0.0

	new Float:origin[3], Float:diff[3], Float:norm[3]
	pev(index, pev_origin, origin)
	vec_sub(point, origin, diff)
	diff[2] = 0.0
	vec_normalize(diff, norm)

	new Float:dot, Float:fov
	dot = vec_dot(norm, angles)
	pev(index, pev_fov, fov)
	if (dot >= floatcos(fov * M_PI / 360))
		return true

	return false
}

get_aim_origin(index, Float:origin[3])
{
	static Float:start[3], Float:view_ofs[3];
	pev(index, pev_origin, start);
	pev(index, pev_view_ofs, view_ofs);
	vec_add(start, view_ofs, start);
	
	static Float:dest[3];
	pev(index, pev_v_angle, dest);
	engfunc(EngFunc_MakeVectors, dest);
	global_get(glb_v_forward, dest);
	vec_mul_scalar(dest, 9999.0, dest);
	vec_add(start, dest, dest);
	
	engfunc(EngFunc_TraceLine, start, dest, 0, index, 0);
	get_tr2(0, TR_vecEndPos, origin);
	
	return 1;
}

bool:is_aiming_at_sky(index)
{
	new target, temp;
	get_user_aiming(index,target,temp);
	if(engfunc(EngFunc_PointContents,target) == CONTENTS_SKY) return true;
	return false;
}

get_ent_in_aim_radius(index, Float:radius) 
{
	static Float:start[3], Float:view_ofs[3];
	static Float:dest[3], Float:origin[3], entclass[32];
	new ent = -1;
	
	pev(index, pev_origin, start)
	pev(index, pev_view_ofs, view_ofs)
	vec_add(start, view_ofs, start)
	pev(index, pev_v_angle, dest)
	engfunc(EngFunc_MakeVectors, dest)
	global_get(glb_v_forward, dest)
	vec_mul_scalar(dest, 9999.0, dest)
	vec_add(start, dest, dest)
	engfunc(EngFunc_TraceLine, start, dest, 0, index, 0)
	get_tr2(0, TR_vecEndPos, origin)
	while((ent = engfunc(EngFunc_FindEntityInSphere, ent, origin, radius)) != 0)
	{
		pev(ent, pev_classname, entclass, 32)
		if(equal(entclass, MEDKITCLASS) || equal(entclass, RECHARGECLASS)) return ent;
	}
	return 0
}

Float:ent_distance(ent1, ent2)
{
	new Float:mins1[3], Float:maxs1[3];
	new Float:mins2[3], Float:maxs2[3];
	new Float:dist[3];
	pev(ent1, pev_absmin, mins1);
	pev(ent1, pev_absmax, maxs1);
	pev(ent2, pev_absmin, mins2);
	pev(ent2, pev_absmax, maxs2);
	for (new i = 0; i < 3; ++i)
	{
		if (mins1[i] > maxs2[i]) dist[i] = mins1[i] - maxs2[i];
		else if (mins2[i] > maxs1[i]) dist[i] = mins2[i] - maxs1[i];
	}
	return vector_length(dist);
}

/*bool:is_visible(index, const Float:point[3], ignoremonsters = 0)
{
	new Float:start[3], Float:view_ofs[3];
	pev(index, pev_origin, start);
	pev(index, pev_view_ofs, view_ofs);
	vec_add(start, view_ofs, start);

	engfunc(EngFunc_TraceLine, start, point, ignoremonsters, index, 0);

	new Float:fraction;
	get_tr2(0, TR_flFraction, fraction);
	if (fraction == 1.0)
		return true;

	return false;
}*/

minimize_normal(Float:normal[3])
{
	normal[0] /= 10.0;
	normal[1] /= 10.0;
	normal[2] /= 10.0;
	return 1;
}

Float:abs_f(Float:x)
{
	if(x < 0) return (-1.0 * x);
	return x;
}

equal_f(Float:origin1[3], Float:origin2[3])
{
	new num_equal = (origin1[0] == origin2[0] ? 1 : 0);
	num_equal += (origin1[1] == origin2[1] ? 1 : 0);
	num_equal += (origin1[2] == origin2[2] ? 1 : 0);
	return num_equal;
}

Float:sum_f(Float:origin1[3], Float:origin2[3])
{
	new Float:result[3];
	result[0] = origin1[0] + origin2[0];
	result[1] = origin1[1] + origin2[1];
	result[2] = origin1[2] + origin2[2];
	return result;
}

Float:diff_f(Float:origin1[3], Float:origin2[3])
{
	new Float:result[3];
	result[0] = origin1[0] - origin2[0];
	result[1] = origin1[1] - origin2[1];
	result[2] = origin1[2] - origin2[2];
	return result;
}

Float:cross_product(Float:origin1[3], Float:origin2[3])
{
	new Float:result[3];
	result[0] = origin1[1]*origin2[2] - origin1[2]*origin2[1];
	result[1] = origin1[2]*origin2[0] - origin1[0]*origin2[2];
	result[2] = origin1[0]*origin2[1] - origin1[1]*origin2[0];
	return result;
}


//+++++ Taken from xs.inc (very nice! Many thanks to PM from http://forums.alliedmods.net/index.php +++++
vec_add(const Float:in1[], const Float:in2[], Float:out[])
{
	out[0] = in1[0] + in2[0];
	out[1] = in1[1] + in2[1];
	out[2] = in1[2] + in2[2];
}

vec_sub(const Float:in1[], const Float:in2[], Float:out[])
{
	out[0] = in1[0] - in2[0];
	out[1] = in1[1] - in2[1];
	out[2] = in1[2] - in2[2];
}

vec_mul_scalar(const Float:vec[], Float:scalar, Float:out[])
{
	out[0] = vec[0] * scalar;
	out[1] = vec[1] * scalar;
	out[2] = vec[2] * scalar;
}

vec_normalize(const Float:vec[], Float:out[])
{
	new Float:invlen = xs_rsqrt(vec[0]*vec[0] + vec[1]*vec[1] + vec[2]*vec[2]);
	out[0] = vec[0] * invlen;
	out[1] = vec[1] * invlen;
	out[2] = vec[2] * invlen;
}

Float:xs_rsqrt(Float:x)
{
	return 1.0 / floatsqroot(x);
}
	
Float:vec_dot(const Float:vec1[], const Float:vec2[])
{
	return vec1[0]*vec2[0] + vec1[1]*vec2[1] + vec1[2]*vec2[2];
}

get_station_num(id)
{
	for(new m = 0; m < g_medkit_count; m++)
		if(g_medkit_id[m] == id) return m;

	for(new r = 0; r < g_recharge_count; r++)
		if(g_recharge_id[r] == id) return r;

	return -1;
}

//+++++ Manipulate the user armor ++++++
set_realarmor(id, armor=2)
{
	if(is_module_loaded("cstrike") != -1)
	{
		set_pdata_int(id, OFFSET_ARMORTYPE, armor, OFFSET_LINUX);
		message_begin(MSG_ONE, g_umsgA, {0,0,0}, id);
		write_byte(1);
		message_end();
	}
}

Аватар
LoShIaA
Извън линия
Потребител
Потребител
Мнения: 323
Регистриран на: 20 Окт 2016, 14:44
Местоположение: Стара Загора
Се отблагодари: 120 пъти
Получена благодарност: 9 пъти

Health Armor Stations плъгина да не ти прави 100 кръвта, когато имаш над 100 и използваш станция

Мнение от LoShIaA » 23 Окт 2017, 16:27

Работи вече супер. Благодаря.

Заключено
  • Подобни теми
    Отговори
    Преглеждания
     Последно мнение

Обратно към “Заявки за плъгини”

Кой е на линия

Потребители разглеждащи този форум: 0 регистрирани и 5 госта