Кода:
Код за потвърждение: Избери целия код
/**********************************************************************************
* 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();
}
}