[Cerere] Modificare plugin

Modificari necesare ale pluginurilor

Moderators: Moderatori ajutatori, Moderatori, Echipa eXtreamCS.com

Post Reply
diavolu111
Membru, skill +1
Membru, skill +1
Posts: 419
Joined: 11 Oct 2014, 18:18
Detinator Steam: Da
Fond eXtream: 0
Location: Alba Iulia
Has thanked: 28 times
Been thanked: 6 times
Contact:

09 Mar 2020, 17:20

As vrea daca se poate sa modificati urmatorul plugin:

Code: Select all

/*******************************************************************************
			Molotov Cocktail
			  Version 3.20
		Maintained by: DynamicBits (Andy)

* Commands:
- say molotov - Buy a molotov
- say /molotov - Buy a molotov
- molotov_give <player|@all|@t|@ct|@al|@ax> - Gives molotovs to a player, a team, or everyone
- molotov_cocktail [0|1] - Enable/disable the plugin (If no arguments, show the status)
- molotov_override [0|1] - Enable/disable the HE grenade override (If no arguments, show the status)

* Cvars
- molotov_enabled - Enable/disable the plugin [1 = enabled; 0 = disabled] [default = 1]
- molotov_price - Set the molotov price [default = 1200]
- molotov_damage - Set the damage done by initial molotov explosion [default = 50.0]
- molotov_radius - Set the radius of molotov damage [default = 150.0]
- molotov_firetime - Duration (in seconds) of fire effects, sounds, etc. [default = 6]
- molotov_firedamage - Amount of damage done by fire effects (every 0.2 secs). [default = 3]
- molotov_ff - Disable(0)/enable(1) the ability to damage/kill someone on your team with molotov. [default = 1] (Was molotov_tk)
- molotov_override_he - Override the original hegrenade automaticly with molotov. [default = 0] (Was molotov_tempoverride)
- molotov_max - Max num of molotovs able to carry. [default = 1] (Does not work with override)
- molotov_inmenu - Puts molotov in the end of the equipment buymenu (old menu, not VGUI). [default = 0]
		   (If the override cvar is enabled the hegrenade will be replaced instead.)
- molotov_buyzone - Do you have to be in buyzone? [default = 1] (If molotov_inmenu=1, this is ignored)
- molotov_menu - Enables menu at beginning of each round [default = 0] (Was amx_molotovmenu)

* Required Modules:
- Fakemeta
- Fun
- Cstrike
- CSX

* Changelog/Credit:
- DynamicBits
  * Version 3.20 (2008-11-20)
    - My first public release
    - Finally tracked down and fixed the intermittent crashing problem (I hope!)
    - Modified default damage values
    - molotov_cocktail/molotov_override commands now change settings *or* display status
    - Broken molotov model stays closer to the explosion (looks more realistic)
    - Task IDs are now guaranteed to be unique
    - Modified anti-lag calculations to be more accurate (less likely to lag)
    - Changed amx_molotovmenu CVAR to molotov_menu
    - Changed molotov_tk CVAR to molotov_ff
    - Changed molotov_tempoverride CVAR to molotov_override_he
    - Preparation for support of mods other than Counter-Strike
    - Fixed lots of coding mistakes
    - Optimized several sections of code
    - Corrected grammar/typos
    - Clean up code (Removed unused code/unhelpful comments, fixed formatting, and semicolons!)
- Raffe (CantShoot)
  * (Unversioned release)
    - Originally fixed plugin to run on Linux servers
    - Added optional menu to purchase molotov cocktails each round
    - Moved models and sounds into proper molotov/ subdirectories
    - Fixed molotovs not being reset upon player disconnect
    - (Almost) fixed molotovs not being removed for new round
    - Added @all/@ct/@t arguments to cmd_MolotovGive
    - Changed some models/sound
- [ --<-@ ] Black Rose
  * Version 3.0-3.1c ?
    - Unknown changes
- SAMURAI
  * Original plugin author


*/

#pragma semicolon 1
#include <amxmodx>
#include <amxmisc>
#include <fakemeta>
#include <cstrike>
#include <csx>
#include <fun>
#include <fakemeta_util>

// Uncomment the following line to enable debug logging.
//#define MOLOTOV_DEBUG

#define AUTHORS "DynamicBits"

#define ADMIN_ACCESS ADMIN_KICK

#define ANTI_LAGG 7.0	// Defines max calculations before a flame is spawned without check if onground
// This is to prevent lagg at really narrow ents where you could end up with 400 calculations per flame
// Suggested: <= 10

#define MOLOTOV_HARD_LIMIT 10	// Maximum molotov cocktails this code is capable of handling without bugs
				// Also how many cocktails people get with molotov_give command

#define MOLOTOV_MENU_KEYS MENU_KEY_0|MENU_KEY_1|MENU_KEY_2	// Choices to look for with optional menu

#define MOLOTOV_TASKID_BASE 1000				// What is the lowest task ID?
#define MOLOTOV_TASKID_OFFSET MOLOTOV_HARD_LIMIT
#define MOLOTOV_TASKID_BASE1 MOLOTOV_TASKID_BASE				 // By default, with 32 players, task ids
#define MOLOTOV_TASKID_BASE2 MOLOTOV_TASKID_BASE1 + (MOLOTOV_TASKID_OFFSET * 32) // from 1000 to 1959 can
#define MOLOTOV_TASKID_BASE3 MOLOTOV_TASKID_BASE2 + (MOLOTOV_TASKID_OFFSET * 32) // potentially be used used.

#define TEAM_UNASSIGNED 0
#define TEAM_ONE	1
#define TEAM_TWO	2
#define TEAM_SPECTATOR	3

new pEnabled, pPrice, pMlDamage, pMlRadius, pFireTime, pOverride;
new pFriendlyFire, pFireDmg, pMaxMolotovs, pBuyMenu, pBuyZone, pMolotovMenu;

new gmsgScoreInfo, gmsgDeathMsg;

new g_pAllocModel, g_vAllocModel;

new g_frags[33];
new g_hasMolotov[33];
new g_restarted;
new g_MaxPlayers;
new g_bomb_map;

new firespr, smokespr[2];

new last_Molotov_ent;
new g_Molotov_offset[33];

new g_g;

public plugin_init() {

	register_plugin("Molotov Cocktail", "3.20", AUTHORS);

	register_menucmd(register_menuid("Buy Molotov Coctail"), MOLOTOV_MENU_KEYS, "giveMolotov");
#if defined MOLOTOV_DEBUG
	register_clcmd("molotov_menutest", "show_molotov_menu");
#endif

	register_clcmd("say /molotov", "buy_molotov");

	register_concmd("molotov_give", "cmd_MolotovGive", ADMIN_ACCESS, "<player|@all|@t|@ct|@al|@ax> - Gives free molotov cocktails (default=10)");
	register_concmd("molotov_override", "cmd_Override", ADMIN_ACCESS, "[0|1] - Enable/disable the HE grenade override (If no arguments, show the status)");
	register_concmd("molotov_cocktail", "cmd_PluginStatus", ADMIN_ACCESS, "[0|1] - Enable/disable the plugin (If no arguments, show the status)");

	pEnabled = register_cvar("molotov_enabled", "1", FCVAR_SPONLY);
	pOverride = register_cvar("molotov_override_he", "0", FCVAR_SPONLY);
	pPrice = register_cvar("molotov_price", "4000", FCVAR_SPONLY);
	pMlDamage = register_cvar("molotov_damage", "50.0", FCVAR_SPONLY);
	pMlRadius = register_cvar("molotov_radius", "150.0", FCVAR_SPONLY);
	pFireTime = register_cvar("molotov_firetime", "7", FCVAR_SPONLY);
	pFireDmg = register_cvar("molotov_firedamage", "4", FCVAR_SPONLY);
	pFriendlyFire = register_cvar("molotov_ff", "0", FCVAR_SPONLY);
	pMaxMolotovs = register_cvar("molotov_max", "1", FCVAR_SPONLY);
	pBuyMenu = register_cvar("molotov_inmenu", "0", FCVAR_SPONLY);
	pBuyZone = register_cvar("molotov_buyzone", "1", FCVAR_SPONLY);
	pMolotovMenu = register_cvar("molotov_menu", "0", FCVAR_SPONLY);

	register_event("CurWeapon", "Event_CurWeapon", "be", "1=1");
	register_event("HLTV", "event_new_round", "a", "1=0", "2=0");
	register_event("TextMsg", "Event_GameRestart", "a", "2=#Game_Commencing", "2=#Game_will_restart_in");
	register_event("DeathMsg", "event_DeathMsg", "a");

	register_event("ShowMenu", "event_BuyMenuT", "b", "4=#T_BuyItem", "1=575");
	register_event("ShowMenu", "event_BuyMenuCT", "b", "4=#CT_BuyItem", "1=703");
	register_event("ShowMenu", "event_BuyMenuT", "b", "4=#DT_BuyItem", "1=575");
	register_event("ShowMenu", "event_BuyMenuCT", "b", "4=#DCT_BuyItem", "1=767");

	register_logevent("logevent_Round_End", 2, "1=Round_End");

	register_menucmd(register_menuid("#CT_BuyItem"), 1023, "handle_BuyMenuCT");
	register_menucmd(register_menuid("#T_BuyItem"), 1023, "handle_BuyMenuT");

	register_forward(FM_EmitSound, "fw_EmitSound");

	g_MaxPlayers = get_maxplayers();

	gmsgScoreInfo = get_user_msgid("ScoreInfo");
	gmsgDeathMsg = get_user_msgid("DeathMsg");

	g_pAllocModel = engfunc(EngFunc_AllocString, "models/molotov/p_molotov.mdl");
	g_vAllocModel = engfunc(EngFunc_AllocString, "models/molotov/v_molotov.mdl");

	g_bomb_map = engfunc(EngFunc_FindEntityByString, g_MaxPlayers, "classname", "info_bomb_target") ? 1 : 0;
}

public plugin_precache() {

	firespr = precache_model("sprites/flame.spr");

	smokespr[0] = precache_model("sprites/black_smoke3.spr");
	smokespr[1] = precache_model("sprites/steam1.spr");

	precache_sound("molotov/molotov_fire.wav");

	precache_model("models/molotov/p_molotov.mdl");
	precache_model("models/molotov/v_molotov.mdl");
	precache_model("models/molotov/w_molotov.mdl");
	precache_model("models/molotov/w_broke_molotov.mdl");

}

public client_disconnect(id) {
	g_hasMolotov[id] = 0;
}

public fw_EmitSound(ent, channel, sample[]) {

	if (equal(sample[8], "he_bounce", 9)) {

		new model[32];
		pev(ent, pev_model, model, 31);

		if (equal(model[9], "lotov/w_molotov.mdl")) {
			if (last_Molotov_ent != ent) {
				new Float:fFriction, Float:fVelocity[3];

				pev(ent, pev_friction, fFriction);
				pev(ent, pev_velocity, fVelocity);

				fFriction *= 1.3;	// Increase friction to make it look more realistic
				set_pev(ent, pev_friction, fFriction);
#if defined MOLOTOV_DEBUG
				log_amx("[MC] ent:%d Friction:%f Velocity:%f/%f/%f ====================", ent, fFriction, fVelocity[0], fVelocity[1], fVelocity[2]);
#endif
				last_Molotov_ent = ent;
				grenade_explode(ent);

				return FMRES_SUPERCEDE;
#if defined MOLOTOV_DEBUG
			} else {
				log_amx("[MC] last_Molotov_ent(%d) ent(%d)", last_Molotov_ent, ent);
#endif
			}
		}
	}
	return FMRES_IGNORED;
}

public Event_CurWeapon(id) {

	if (!get_pcvar_num(pEnabled) || !is_user_alive(id)) {
		return PLUGIN_CONTINUE;
	}

	if (!g_hasMolotov[id] && !get_pcvar_num(pOverride)) {
		return PLUGIN_CONTINUE;
	}

	new WeaponID = get_user_weapon(id, WeaponID, WeaponID);

	if (WeaponID != CSW_HEGRENADE) {
		return PLUGIN_CONTINUE;
	}

	set_pev(id, pev_viewmodel, g_vAllocModel);
	set_pev(id, pev_weaponmodel, g_pAllocModel);
	set_pev(id, pev_weaponanim, 9);

	return PLUGIN_CONTINUE;
}

public Event_GameRestart() {
	g_restarted = 1;
}

public event_DeathMsg() {
	g_hasMolotov[read_data(2)] = 0;
}

public logevent_Round_End() {
#if defined MOLOTOV_DEBUG
	log_amx("[MC] ========== Round_End ==========");
#endif
	reset_tasks();
}

stock reset_tasks() {
#if defined MOLOTOV_DEBUG
	new tmpdbgid;
#endif
	for (new i; i < g_MaxPlayers; i++) {
		for (new o; o < MOLOTOV_TASKID_OFFSET; o++) {	//TODO DEBUG: Verify this fixes the tasks not reset at new round issue
			if (task_exists(MOLOTOV_TASKID_BASE1 + (MOLOTOV_TASKID_OFFSET * i) + o)) {
				remove_task(MOLOTOV_TASKID_BASE1 + (MOLOTOV_TASKID_OFFSET * i) + o);
#if defined MOLOTOV_DEBUG
				tmpdbgid = MOLOTOV_TASKID_BASE1 + (MOLOTOV_TASKID_OFFSET * i) + o;
				log_amx("[MC] %d exists. ----------==========----------", tmpdbgid);
#endif
			}

			if (task_exists(MOLOTOV_TASKID_BASE2 + (MOLOTOV_TASKID_OFFSET * i) + o)) {
				remove_task(MOLOTOV_TASKID_BASE2 + (MOLOTOV_TASKID_OFFSET * i) + o);
#if defined MOLOTOV_DEBUG
				tmpdbgid = MOLOTOV_TASKID_BASE2 + (MOLOTOV_TASKID_OFFSET * i) + o;
				log_amx("[MC] %d exists. ----------==========----------", tmpdbgid);
#endif
			}

			if (task_exists(MOLOTOV_TASKID_BASE3 + (MOLOTOV_TASKID_OFFSET * i) + o)) {
				remove_task(MOLOTOV_TASKID_BASE3 + (MOLOTOV_TASKID_OFFSET * i) + o);
#if defined MOLOTOV_DEBUG
				tmpdbgid = MOLOTOV_TASKID_BASE3 + (MOLOTOV_TASKID_OFFSET * i) + o;
				log_amx("[MC] %d exists. ----------==========----------", tmpdbgid);
#endif
			}
		}
	}
}

public event_new_round(id) {
#if defined MOLOTOV_DEBUG
	log_amx("[MC] ========== event_new_round ==========");
#endif
	if (!get_pcvar_num(pEnabled)) {
		return PLUGIN_CONTINUE;
	}

	reset_tasks();	// DEBUG

	if (get_pcvar_num(pMolotovMenu)) {
		show_molotov_menu(id);
	}

	for (new i; i < g_MaxPlayers; i++) {
		if (g_frags[i] && is_user_connected(i)) {
			set_user_frags(i, get_user_frags(i) + g_frags[i]);
		}
		g_frags[i] = 0;
	}

	if (g_restarted) {
		for (new i; i < g_MaxPlayers; i++) {
			g_hasMolotov[i] = 0;
		}
		g_restarted = 0;
	}

	if (get_pcvar_num(pOverride)) {
		set_molotovs();
	} else {
		reset_molotovs();
	}

	return PLUGIN_CONTINUE;
}

public cmd_Override(id, level, cid) {	

	if (!cmd_access(id, level, cid, 1)) {		// First argument (passed to molotov_override) is optional
		return PLUGIN_HANDLED;
	}

	if (!get_pcvar_num(pEnabled)) {
		return PLUGIN_HANDLED;
	}

	if (read_argc() == 1) {				// No arguments; Display status
		client_print(id, print_console, "Override is currently %s.", get_pcvar_num(pOverride) ? "enabled" : "disabled");
		return PLUGIN_HANDLED;
	}

	new arg[2];
	read_argv(1, arg, 1);

	new num = str_to_num(arg);

	if ((num < 0) || (num > 1) || (!isdigit(arg[0]))) {	// If less than 0 or greater than 1 or not a digit
		if (id) {
			client_print(id, print_console, "Invalid argument(%s). Valid arguments are ^"0^" and ^"1^".", arg);
		} else {
			server_print("Invalid argument(%s). Valid arguments are ^"0^" and ^"1^".", arg);
		}
		return PLUGIN_HANDLED;
	}

	if (num == get_pcvar_num(pOverride)) {
		if (id) {
			client_print(id, print_console, "Override is already %s.", num ? "enabled" : "disabled");
		} else {
			server_print("Override is already %s.", num ? "enabled" : "disabled");
		}
		return PLUGIN_HANDLED;
	}

	set_pcvar_num(pOverride, num);

	if (id) {
		client_print(id, print_console, "Override was %s.", num ? "enabled" : "disabled");
	} else {
		server_print("Override was %s.", num ? "enabled" : "disabled");
	}

	if (num) {
		set_molotovs();
	} else {
		reset_molotovs();
	}

	return PLUGIN_HANDLED;
}

public cmd_PluginStatus(id, level, cid) {
	if (!cmd_access(id, level, cid, 1)) {		// First argument (passed to molotov_cocktail) is optional
		return PLUGIN_HANDLED;
	}

	if (read_argc() == 1) {				// No arguments; Display status
		client_print(id, print_console, "Plugin is currently %s.", get_pcvar_num(pEnabled) ? "enabled" : "disabled");
		return PLUGIN_HANDLED;
	}

	new arg[2];
	read_argv(1, arg, 1);

	new num = str_to_num(arg);

	if ((num < 0) || (num > 1) || (!isdigit(arg[0]))) {	// If less than 0 or greater than 1 or not a digit
		if (id) {
			client_print(id, print_console, "Invalid argument(%s). Valid arguments are ^"0^" and ^"1^".", arg);
		} else {
			server_print("Invalid argument(%s). Valid arguments are ^"0^" and ^"1^".", arg);
		}
		return PLUGIN_HANDLED;
	}

	if (num == get_pcvar_num(pEnabled)) {
		if (id) {
			client_print(id, print_console, "Plugin is already %s.", num ? "enabled" : "disabled");
		} else {
			server_print("Plugin is already %s.", num ? "enabled" : "disabled");
		}
		return PLUGIN_HANDLED;
	}

	set_pcvar_num(pEnabled, num);

	if (id) {
		client_print(id, print_console, "Plugin was %s.", num ? "enabled" : "disabled");
	} else {
		server_print("Plugin was %s.", num ? "enabled" : "disabled");
	}

	if (num && get_pcvar_num(pOverride)) {
		set_molotovs();
	} else {
		reset_molotovs();
	}
	return PLUGIN_HANDLED;
}

public cmd_MolotovGive(id, level, cid) {

#if defined MOLOTOV_DEBUG
	log_amx("[MC] cmd_MolotovGive");
#endif
	if (!cmd_access(id, level, cid, 2)) {
		return PLUGIN_HANDLED;
	}

	new Arg1[64], target;
	read_argv(1, Arg1, 63);

	new adminName[32];
	get_user_name(id, adminName, 31);

	new targetTeam, targetTeamName[32];
	new Players[32], iNum;
#if defined MOLOTOV_DEBUG
	log_amx("[MC] cmd_MolotovGive Arg1[0](%s) Arg1[1](%s)", Arg1[0], Arg1[1]);
#endif
	if (Arg1[0] == '@') {

		if (equali(Arg1[1], "all")) {
			targetTeam = 0;
		} else if (equali(Arg1[1], "t") || equali(Arg1[1], "al")) {	// CS_TEAM_T or ALLIES
			targetTeam = TEAM_ONE;
		} else if (equali(Arg1[1], "ct") || equali(Arg1[1], "ax")) {	// CS_TEAM_CT or AXIS
			targetTeam = TEAM_TWO;
		}

		get_players(Players, iNum, "ac");	// Bots don't understand molotov cocktails

		for (new i = 0; i < iNum; ++i) {
			target = Players[i];

			if ((targetTeam == 0) || (get_user_team(target) == targetTeam)) {
				g_hasMolotov[target] = MOLOTOV_HARD_LIMIT;

				give_item(target, "weapon_hegrenade");
				cs_set_user_bpammo(target, CSW_HEGRENADE, MOLOTOV_HARD_LIMIT);
				emit_sound(target, CHAN_WEAPON, "items/gunpickup2.wav", VOL_NORM, ATTN_NORM, 0, PITCH_NORM);
			}
		}

		switch(targetTeam) {
			case 0: {
				targetTeamName = "everyone";
			}
			case 1: {
				if (cstrike_running()) {
					targetTeamName = "all terrorists";
				} else if (is_running("dod")) {
					targetTeamName = "all allies";
				} else {
					targetTeamName = "team 1";
				}
			}
			case 2: {
				if (cstrike_running()) {
					targetTeamName = "all ct's";
				} else if (is_running("dod")) {
					targetTeamName = "all axis";
				} else {
					targetTeamName = "team 2";
				}
			}
		}
		client_print(0, print_chat, "ADMIN %s: has given %s %d Molotov Cocktails!", adminName, targetTeamName, MOLOTOV_HARD_LIMIT);

	} else {

		target = cmd_target(id, Arg1, 0);

		if (!is_user_connected(target) || !is_user_alive(target)) {
			return PLUGIN_HANDLED;
		}

		new targetName[32];
		get_user_name(target, targetName, 31);

		g_hasMolotov[target] = MOLOTOV_HARD_LIMIT;

		give_item(target, "weapon_hegrenade");
		cs_set_user_bpammo(target, CSW_HEGRENADE, MOLOTOV_HARD_LIMIT);

		emit_sound(target, CHAN_WEAPON, "items/gunpickup2.wav", VOL_NORM, ATTN_NORM, 0, PITCH_NORM);

		client_print(target, print_chat, "ADMIN %s: has given you %d Molotov Cocktails!", adminName, MOLOTOV_HARD_LIMIT);

	}
	return PLUGIN_HANDLED;
}

public buy_molotov(id) {

	if (!get_pcvar_num(pEnabled)) {
		return PLUGIN_HANDLED;
	}

	if (get_pcvar_num(pOverride)) {
		if (get_pcvar_num(pBuyMenu)) {
			client_print(id, print_center, "Buy them in the buy equipment menu.");
		} else {
			client_print(id, print_center, "Just buy a HE grenade and get molotov automatically!");
		}
		return PLUGIN_HANDLED;
	}

	if (!is_user_alive(id)) {
		client_print(id, print_center, "Sen Molotov Kokteyli Alamassin Cunku Olusun");
		return PLUGIN_HANDLED;
	}

	if (!cs_get_user_buyzone(id) && get_pcvar_num(pBuyZone)) {
		client_print(id, print_center, "Burada Molotov Kokteyli Alamassin.");
		return PLUGIN_HANDLED;
	}

	new money = cs_get_user_money(id);

	if (money < get_pcvar_num(pPrice)) {
		client_print(id, print_center, "Molotov Kokteyli Almak Icin Yeterli Paran Yok");
		return PLUGIN_HANDLED;
	}

	if (g_hasMolotov[id] == get_pcvar_num(pMaxMolotovs)) {
		if (g_hasMolotov[id] == 1) {
			client_print(id, print_center, "Sen Molotov Kokteyline Sahipsin");
		} else {
			client_print(id, print_center, "Sende %d Molotov Cocktail Var.", g_hasMolotov[id]);
		}
		return PLUGIN_HANDLED;
	}

	if (!g_hasMolotov[id] && user_has_weapon(id, CSW_HEGRENADE)) {
		client_print(id, print_center, "You already have a HE Grenade.");
		return PLUGIN_HANDLED;
	}

	cs_set_user_money(id, money - get_pcvar_num(pPrice));
	give_item(id, "weapon_hegrenade");
	cs_set_user_bpammo(id, CSW_HEGRENADE, ++g_hasMolotov[id]);
	client_print(id, print_chat, "Sen Molotov Kokteyli Aldin");

	return PLUGIN_HANDLED;
}

public event_BuyMenuCT(id) {

	if (!get_pcvar_num(pEnabled) || !get_pcvar_num(pBuyMenu)) {
		return PLUGIN_CONTINUE;
	}

	new Override = get_pcvar_num(pOverride);

	new menu[1024];
	new len = formatex(menu, 1023, "\yBuy Equipment\R$ Cost");

	len += formatex(menu[len], 1023-len, "^n^n\w1. Kevlar Vest\R\y650");
	len += formatex(menu[len], 1023-len, "^n\w2. Kevlar Vest & Helmet\R\y1000");
	len += formatex(menu[len], 1023-len, "^n\w3. Flashbang\R\y200");

	if (Override) {
		len += formatex(menu[len], 1023-len, "^n\w4. Molotov Cocktail\R\y%d", get_pcvar_num(pPrice));
	} else {
		len += formatex(menu[len], 1023-len, "^n\w4. HE Grenade\R\y300");
	}

	len += formatex(menu[len], 1023-len, "^n\w5. Smoke Grenade\R\y300");
	len += formatex(menu[len], 1023-len, "^n\w6. NightVision Goggles\R\y1250");
	len += formatex(menu[len], 1023-len, "^n\%c7. Defuse Kit\R\y200 ", g_bomb_map ? 'w' : 'd');
	len += formatex(menu[len], 1023-len, "^n\w8. Tactical Shield\R\y2200");

	if (!Override) {
		len += formatex(menu[len], 1023-len, "^n\w9. Molotov Cocktail\R\y%d", get_pcvar_num(pPrice));
	}

	len += formatex(menu[len], 1023-len, "^n^n\w0. Exit");

	show_menu(id, read_data(1)|MENU_KEY_9, menu, -1, "#CT_BuyItem");

	return PLUGIN_HANDLED;
}

public event_BuyMenuT(id) {

	if (!get_pcvar_num(pEnabled) || !get_pcvar_num(pBuyMenu)) {
		return PLUGIN_CONTINUE;
	}

	new Override = get_pcvar_num(pOverride);

	new menu[1024];
	new len = formatex(menu, 1023, "\yBuy Equipment\R$ Cost");
	len += formatex(menu[len], 1023-len, "^n^n\w1. Kevlar Vest\R\y650");
	len += formatex(menu[len], 1023-len, "^n\w2. Kevlar Vest & Helmet\R\y1000");
	len += formatex(menu[len], 1023-len, "^n\w3. Flashbang\R\y200");

	if (Override) {
		len += formatex(menu[len], 1023-len, "^n\w4. Molotov Cocktail\R\y%d", get_pcvar_num(pPrice));
	} else {
		len += formatex(menu[len], 1023-len, "^n\w4. HE Grenade\R\y300");
	}

	len += formatex(menu[len], 1023-len, "^n\w5. Smoke Grenade\R\y300");
	len += formatex(menu[len], 1023-len, "^n\w6. NightVision Goggles\R\y1250");

	if (!Override) {
		len += formatex(menu[len], 1023-len, "^n\w7. Molotov Cocktail\R\y%d", get_pcvar_num(pPrice));
	}

	len += formatex(menu[len], 1023-len, "^n^n\w0. Exit");

	show_menu(id, read_data(1)|MENU_KEY_7, menu, -1, "#T_BuyItem");

	return PLUGIN_HANDLED;
}

public handle_BuyMenuCT(id, key) {

	if (key == (get_pcvar_num(pOverride) ? 3 : 8)) {
		handle_BuyMenu(id);
		return PLUGIN_HANDLED;
	}

	return PLUGIN_CONTINUE;
}

public handle_BuyMenuT(id, key) {

	if (key == (get_pcvar_num(pOverride) ? 3 : 6)) {
		handle_BuyMenu(id);
		return PLUGIN_HANDLED;
	}

	return PLUGIN_CONTINUE;
}

stock handle_BuyMenu(id) {

	new money = cs_get_user_money(id);

	if (money < get_pcvar_num(pPrice)) {
		client_print(id, print_center, "Molotov Kokteyli Alman Icin Yeterli Paran Yok");
		return PLUGIN_HANDLED;
	}

	if (g_hasMolotov[id] == get_pcvar_num(pMaxMolotovs)) {
		if (g_hasMolotov[id] == 1) {
			client_print(id, print_center, "Sen Molotov Kokteyline Sahipsin");
		} else {
			client_print(id, print_center, "Sende %d Molotov Cocktail Var.", g_hasMolotov[id]);
		}
		return PLUGIN_HANDLED;
	} else if (!g_hasMolotov[id] && user_has_weapon(id, CSW_HEGRENADE)) {
		client_print(id, print_center, "You already have a HE Grenade.");
		return PLUGIN_HANDLED;
	}

	cs_set_user_money(id, money - get_pcvar_num(pPrice));
	give_item(id, "weapon_hegrenade");
	cs_set_user_bpammo(id, CSW_HEGRENADE, ++g_hasMolotov[id]);
	client_print(id, print_chat, "You got a Molotov Cocktail!");

	return PLUGIN_HANDLED;
}

public grenade_throw(id, ent, wid) {

	if (!get_pcvar_num(pEnabled) || !is_user_connected(id) || wid != CSW_HEGRENADE) {
		return PLUGIN_CONTINUE;
	}

	if (!g_hasMolotov[id] && !get_pcvar_num(pOverride)) {
		return PLUGIN_CONTINUE;
	}

	g_hasMolotov[id]--;
	engfunc(EngFunc_SetModel, ent, "models/molotov/w_molotov.mdl");
	set_pev(ent, pev_nextthink, 99999.0);

	return PLUGIN_CONTINUE;
}

public grenade_explode(ent) {

	new param[6], iOrigin[3];
	new Float:fOrigin[3];
	new owner = pev(ent, pev_owner);
	new ent2 = engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, "info_target"));

	pev(ent, pev_origin, fOrigin);

#if defined MOLOTOV_DEBUG
	new iOwnerAlive = is_user_alive(owner);
	new iOwnerConnected = is_user_connected(owner);
	new iEnt2Valid = pev_valid(ent2);
	log_amx("[MC] grenade_explode ent(%d) owner(%d) ent2(%d) iOwnerAlive(%d) iOwnerConnected(%d) iEnt2Valid(%d)", ent, owner, ent2, iOwnerAlive, iOwnerConnected, iEnt2Valid);
#endif

	param[0] = ent;
	param[1] = ent2;
	param[2] = owner;
	param[3] = iOrigin[0] = floatround(fOrigin[0]);
	param[4] = iOrigin[1] = floatround(fOrigin[1]);
	param[5] = iOrigin[2] = floatround(fOrigin[2]);

	emit_sound(ent, CHAN_AUTO, "molotov/molotov_fire.wav", VOL_NORM, ATTN_NORM, 0, PITCH_NORM);

	engfunc(EngFunc_SetModel, ent, "models/molotov/w_broke_molotov.mdl");

	random_fire(iOrigin, ent2);
	radius_damage(owner, fOrigin, get_pcvar_float(pMlDamage), get_pcvar_float(pMlRadius), DMG_BLAST);

	new Float:FireTime = get_pcvar_float(pFireTime);

	if (++g_Molotov_offset[owner] == MOLOTOV_HARD_LIMIT) {
		g_Molotov_offset[owner] = 0;
	}

	set_task(0.2, "fire_damage", MOLOTOV_TASKID_BASE1 + (MOLOTOV_TASKID_OFFSET * (owner - 1)) + g_Molotov_offset[owner], param, 6, "a", floatround(FireTime / 0.2, floatround_floor));
	set_task(1.0, "fire_sound", MOLOTOV_TASKID_BASE2 + (MOLOTOV_TASKID_OFFSET * (owner - 1)) + g_Molotov_offset[owner], param, 6, "a", floatround(FireTime) - 1);
	set_task(FireTime, "fire_stop", MOLOTOV_TASKID_BASE3 + (MOLOTOV_TASKID_OFFSET * (owner - 1)) + g_Molotov_offset[owner], param, 6);

	return PLUGIN_CONTINUE;
}

public fire_sound(param[]) {
	emit_sound(param[1], CHAN_AUTO, "molotov/molotov_fire.wav", VOL_NORM, ATTN_NORM, 0, PITCH_NORM);
}

public fire_stop(param[]) {
	g_g = 0;

	if (pev_valid(param[0])) { engfunc(EngFunc_RemoveEntity, param[0]); }
	if (pev_valid(param[1])) { engfunc(EngFunc_RemoveEntity, param[1]); }

	if ((last_Molotov_ent = (param[0]))) {
		last_Molotov_ent = 0;
	}
}

public fire_damage(param[]) {

	new iOrigin[3], Float:fOrigin[3];
	iOrigin[0] = param[3];
	iOrigin[1] = param[4];
	iOrigin[2] = param[5];

	random_fire(iOrigin, param[1]);

	IVecFVec(iOrigin, fOrigin);
	radius_damage(param[2], fOrigin, get_pcvar_float(pFireDmg), get_pcvar_float(pMlRadius), DMG_BURN, 0);
}

stock radius_damage(attacker, Float:origin[3], Float:damage, Float:range, dmgtype, calc = 1) {

	new Float:pOrigin[3], Float:dist, Float:tmpdmg;
	new i, ateam = get_user_team(attacker), iFF = get_pcvar_num(pFriendlyFire);

	while (i++ < g_MaxPlayers) {
		if (!is_user_alive(i)) {
			continue;
		}

		if (!iFF && ateam == get_user_team(i)) {
			continue;
		}

		pev(i, pev_origin, pOrigin);
		dist = get_distance_f(origin, pOrigin);

		if (dist > range) {
			continue;
		}

		if (calc) {
			tmpdmg = damage - (damage / range) * dist;
		} else {
			tmpdmg = damage;
		}

		if (pev(i, pev_health) < tmpdmg) {
			kill(attacker, i);
		} else {
			fm_fakedamage(i, "molotov", tmpdmg, dmgtype);
		}
	}

	while ((i = engfunc(EngFunc_FindEntityInSphere, i, origin, range))) {	// warning 211: possibly unintended assignment
		if (pev(i, pev_takedamage)) {
			if (calc) {
				pev(i, pev_origin, pOrigin);
				tmpdmg = damage - (damage / range) * get_distance_f(origin, pOrigin);
			} else {
				tmpdmg = damage;
			}
			fm_fakedamage(i, "molotov", tmpdmg, dmgtype);
		}
	}
}

stock random_fire(Origin[3], ent) {

	new range = get_pcvar_num(pMlRadius);
	new iOrigin[3];

	for (new i = 1; i <= 5; i++) {

		g_g = 1;

		iOrigin[0] = Origin[0] + random_num(-range, range);
		iOrigin[1] = Origin[1] + random_num(-range, range);
		iOrigin[2] = Origin[2];
		iOrigin[2] = ground_z(iOrigin, ent);

		while (get_distance(iOrigin, Origin) > range) {
			g_g++;
#if defined MOLOTOV_DEBUG
			//log_amx("[MC] random_fire ent(%d) i(%d) g_g(%d)", ent, i, g_g);
#endif
			iOrigin[0] = Origin[0] + random_num(-range, range);
			iOrigin[1] = Origin[1] + random_num(-range, range);
			iOrigin[2] = Origin[2];

			if (g_g >= ANTI_LAGG) {
				iOrigin[2] = ground_z(iOrigin, ent, 1);
			} else {
				iOrigin[2] = ground_z(iOrigin, ent);
			}
		}

		new rand = random_num(5, 15);

		message_begin(MSG_BROADCAST, SVC_TEMPENTITY);
		write_byte(TE_SPRITE);
		write_coord(iOrigin[0]);
		write_coord(iOrigin[1]);
		write_coord(iOrigin[2] + rand * 5);
		write_short(firespr);
		write_byte(rand);
		write_byte(100);
		message_end();

		if (!(i % 4)) {	// Smoke every 4th flame
			message_begin(MSG_BROADCAST, SVC_TEMPENTITY);
			write_byte(TE_SMOKE);
			write_coord(iOrigin[0]);
			write_coord(iOrigin[1]);
			write_coord(iOrigin[2] + 120);
			write_short(smokespr[random_num(0, 1)]);
			write_byte(random_num(10, 30));
			write_byte(random_num(10, 20));
			message_end();
		}
	}
}

stock kill(k, v) {

	user_silentkill(v);

	new kteam = get_user_team(k);
	new vteam = get_user_team(v);

	new kfrags = get_user_frags(k) + 1;
	new kdeaths = get_user_deaths(k);
	if (kteam == vteam) {
		kfrags = get_user_frags(k) - 2;
	}

	new vfrags = get_user_frags(v);
	new vdeaths = get_user_deaths(v);

	message_begin(MSG_ALL, gmsgScoreInfo);
	write_byte(k);
	write_short(kfrags);
	write_short(kdeaths);
	write_short(0);
	write_short(kteam);
	message_end();

	message_begin(MSG_ALL, gmsgScoreInfo);
	write_byte(v);
	write_short(vfrags + 1);
	write_short(vdeaths);
	write_short(0);
	write_short(vteam);
	message_end();

	message_begin(MSG_ALL, gmsgDeathMsg, {0,0,0}, 0);
	write_byte(k);
	write_byte(v);
	write_byte(0);
	write_string("molotov");
	message_end();

	g_frags[k]++;

	if (kteam != vteam) {
		cs_set_user_money(k, cs_get_user_money(k) + 300);
	} else {
		cs_set_user_money(k, cs_get_user_money(k) - 300);
	}
}

stock ground_z(iOrigin[3], ent, skip = 0, iRecursion = 0) {

#if defined MOLOTOV_DEBUG
	new iEntValid = pev_valid(ent);
	if (iRecursion > 0) {
		log_amx("[MC] ground_z ent(%d) iEntValid(%d) skip(%d) iRecursion(%d)", ent, iEntValid, skip, iRecursion);
	}
#endif
	iOrigin[2] += random_num(5, 80);

	if (!pev_valid(ent)) {	// Fix for: Run time error 10: native error (native "set_pev")
		return iOrigin[2];
	}

	new Float:fOrigin[3];

	IVecFVec(iOrigin, fOrigin);

	set_pev(ent, pev_origin, fOrigin);

	engfunc(EngFunc_DropToFloor, ent);

	if (!skip && !engfunc(EngFunc_EntIsOnFloor, ent)) {
		if (iRecursion >= ANTI_LAGG) {
			skip = 1;
		}
#if defined MOLOTOV_DEBUG
		log_amx("[MC] ground_z ++iRecursion(%d)", ++iRecursion);
		return ground_z(iOrigin, ent, skip, iRecursion);
#else
		return ground_z(iOrigin, ent, skip, ++iRecursion);
#endif
	}

	pev(ent, pev_origin, fOrigin);

	return floatround(fOrigin[2]);
}

stock reset_molotovs() {
	new ent = g_MaxPlayers;
	while ((ent = engfunc(EngFunc_FindEntityByString, ent, "model", "models/molotov/w_molotov.mdl"))) {
		engfunc(EngFunc_SetModel, ent, "models/w_hegrenade.mdl");
	}
}

stock set_molotovs() {
	new ent = g_MaxPlayers;
	while ((ent = engfunc(EngFunc_FindEntityByString, ent, "model", "models/w_hegrenade.mdl"))) {
		engfunc(EngFunc_SetModel, ent, "models/molotov/w_molotov.mdl");
	}
}

// This will run at event New Round if enabled
public show_molotov_menu(id) {
	new menu[192];

	// Get a custom menu title with the price
	// When done it should look something like this:
	// Buy Molotov Cocktail ($1200)...
	new menu_title_text[120], the_molotov_price[7];
	get_cvar_string("molotov_price", the_molotov_price, 6);
	strcat(menu_title_text, "Buy Molotov Cocktail ($", 40);
	strcat(menu_title_text, the_molotov_price, 40);
	strcat(menu_title_text, ")?^n^n1. Yes, I will burn them all...^n2. No, I will kill in some other way...^n^n0. EXIT MENU", 119);

	format(menu, 191, menu_title_text);

	// This shows the menu for 30 seconds, I tried first with get_cvar_num("mp_buytime")*60 , but it didn't work well
	// when using 0.5 as mp_buytime. If you like, just change the time below
	show_menu(id, MOLOTOV_MENU_KEYS, menu, 30);

	return PLUGIN_HANDLED;
}

//Our menu function will get the player id and the key they pressed
public giveMolotov(id, key) {

	//key will start at zero
	if (key == 0) {
		buy_molotov(id);
	} else if (key == 1) {
		client_print(id, print_center, ">You have chosen not to buy a Molotov Coctail<");
	} else {
		client_print(id, print_center, ">You have choosen to exit the molotov menu...<");
	}
}
As vrea sa dea grenada molotov in loc la smoke nu la he. + daca se poate adauga un cvar si pentru VIP (flag t). Gen jucatorii sa poata sa cumpere doar 1 data prin comanda /molotov, dar doar din buy zone, iar VIP-ii sa cumpere de mai multe ori din orice zona.

Daca nu se poate setarea cu VIP macar sa se modifice inlocuirea din HE in SMOKE.

Multumesc :)
RoyalServer 2
User avatar
levin
Scripter eXtreamCS
Scripter eXtreamCS
Posts: 3844
Joined: 24 Aug 2011, 12:24
Detinator Steam: Da
CS Status:
Detinator server CS: ☯∴
SteamID: riseofevo
Reputatie: Scripter eXtreamCS
Nume anterior: Adryyy
Location: ҳ̸Ҳ̸ҳ
Discord: devilclass
Has thanked: 36 times
Been thanked: 594 times
Contact:

10 Mar 2020, 21:18

Code: Select all

/*******************************************************************************
			Molotov Cocktail
			  Version 3.20
		Maintained by: DynamicBits (Andy)

* Commands:
- say molotov - Buy a molotov
- say /molotov - Buy a molotov
- molotov_give <player|@all|@t|@ct|@al|@ax> - Gives molotovs to a player, a team, or everyone
- molotov_cocktail [0|1] - Enable/disable the plugin (If no arguments, show the status)
- molotov_override [0|1] - Enable/disable the HE grenade override (If no arguments, show the status)

* Cvars
- molotov_enabled - Enable/disable the plugin [1 = enabled; 0 = disabled] [default = 1]
- molotov_price - Set the molotov price [default = 1200]
- molotov_damage - Set the damage done by initial molotov explosion [default = 50.0]
- molotov_radius - Set the radius of molotov damage [default = 150.0]
- molotov_firetime - Duration (in seconds) of fire effects, sounds, etc. [default = 6]
- molotov_firedamage - Amount of damage done by fire effects (every 0.2 secs). [default = 3]
- molotov_ff - Disable(0)/enable(1) the ability to damage/kill someone on your team with molotov. [default = 1] (Was molotov_tk)
- molotov_override_he - Override the original hegrenade automaticly with molotov. [default = 0] (Was molotov_tempoverride)
- molotov_max - Max num of molotovs able to carry. [default = 1] (Does not work with override)
- molotov_inmenu - Puts molotov in the end of the equipment buymenu (old menu, not VGUI). [default = 0]
		   (If the override cvar is enabled the hegrenade will be replaced instead.)
- molotov_buyzone - Do you have to be in buyzone? [default = 1] (If molotov_inmenu=1, this is ignored)
- molotov_menu - Enables menu at beginning of each round [default = 0] (Was amx_molotovmenu)

* Required Modules:
- Fakemeta
- Fun
- Cstrike
- CSX

* Changelog/Credit:
- DynamicBits
  * Version 3.20 (2008-11-20)
    - My first public release
    - Finally tracked down and fixed the intermittent crashing problem (I hope!)
    - Modified default damage values
    - molotov_cocktail/molotov_override commands now change settings *or* display status
    - Broken molotov model stays closer to the explosion (looks more realistic)
    - Task IDs are now guaranteed to be unique
    - Modified anti-lag calculations to be more accurate (less likely to lag)
    - Changed amx_molotovmenu CVAR to molotov_menu
    - Changed molotov_tk CVAR to molotov_ff
    - Changed molotov_tempoverride CVAR to molotov_override_he
    - Preparation for support of mods other than Counter-Strike
    - Fixed lots of coding mistakes
    - Optimized several sections of code
    - Corrected grammar/typos
    - Clean up code (Removed unused code/unhelpful comments, fixed formatting, and semicolons!)
- Raffe (CantShoot)
  * (Unversioned release)
    - Originally fixed plugin to run on Linux servers
    - Added optional menu to purchase molotov cocktails each round
    - Moved models and sounds into proper molotov/ subdirectories
    - Fixed molotovs not being reset upon player disconnect
    - (Almost) fixed molotovs not being removed for new round
    - Added @all/@ct/@t arguments to cmd_MolotovGive
    - Changed some models/sound
- [ --<-@ ] Black Rose
  * Version 3.0-3.1c ?
    - Unknown changes
- SAMURAI
  * Original plugin author


*/

#include <amxmodx>
#include <amxmisc>
#include <fakemeta>
#include <cstrike>
#include <csx>
#include <fun>
#include <fakemeta_util>

#define vip_flag "t"
#define is_vip(%1)	(get_user_flags(%1)&read_flags(vip_flag))

// Uncomment the following line to enable debug logging.
//#define MOLOTOV_DEBUG

#define AUTHORS "DynamicBits"

#define ADMIN_ACCESS ADMIN_KICK

#define ANTI_LAGG 7.0	// Defines max calculations before a flame is spawned without check if onground
// This is to prevent lagg at really narrow ents where you could end up with 400 calculations per flame
// Suggested: <= 10

#define MOLOTOV_HARD_LIMIT 10	// Maximum molotov cocktails this code is capable of handling without bugs
				// Also how many cocktails people get with molotov_give command

#define MOLOTOV_MENU_KEYS MENU_KEY_0|MENU_KEY_1|MENU_KEY_2	// Choices to look for with optional menu

#define MOLOTOV_TASKID_BASE 1000				// What is the lowest task ID?
#define MOLOTOV_TASKID_OFFSET MOLOTOV_HARD_LIMIT
#define MOLOTOV_TASKID_BASE1 MOLOTOV_TASKID_BASE				 // By default, with 32 players, task ids
#define MOLOTOV_TASKID_BASE2 MOLOTOV_TASKID_BASE1 + (MOLOTOV_TASKID_OFFSET * 32) // from 1000 to 1959 can
#define MOLOTOV_TASKID_BASE3 MOLOTOV_TASKID_BASE2 + (MOLOTOV_TASKID_OFFSET * 32) // potentially be used used.

#define TEAM_UNASSIGNED 0
#define TEAM_ONE	1
#define TEAM_TWO	2
#define TEAM_SPECTATOR	3

new pEnabled, pPrice, pMlDamage, pMlRadius, pFireTime, pOverride;
new pFriendlyFire, pFireDmg, pMaxMolotovs, pBuyMenu, pBuyZone, pMolotovMenu;

new gmsgScoreInfo, gmsgDeathMsg;

new g_pAllocModel, g_vAllocModel;

new g_frags[33];
new g_hasMolotov[33];
new g_restarted;
new g_MaxPlayers;
new g_bomb_map;

new firespr, smokespr[2];

new last_Molotov_ent;
new g_Molotov_offset[33];

new g_g;

public plugin_init() {

	register_plugin("Molotov Cocktail", "3.20", AUTHORS);

	register_menucmd(register_menuid("Buy Molotov Coctail"), MOLOTOV_MENU_KEYS, "giveMolotov");
#if defined MOLOTOV_DEBUG
	register_clcmd("molotov_menutest", "show_molotov_menu");
#endif

	register_clcmd("say /molotov", "buy_molotov");

	register_concmd("molotov_give", "cmd_MolotovGive", ADMIN_ACCESS, "<player|@all|@t|@ct|@al|@ax> - Gives free molotov cocktails (default=10)");
	register_concmd("molotov_override", "cmd_Override", ADMIN_ACCESS, "[0|1] - Enable/disable the HE grenade override (If no arguments, show the status)");
	register_concmd("molotov_cocktail", "cmd_PluginStatus", ADMIN_ACCESS, "[0|1] - Enable/disable the plugin (If no arguments, show the status)");

	pEnabled = register_cvar("molotov_enabled", "1", FCVAR_SPONLY);
	pOverride = register_cvar("molotov_override_he", "0", FCVAR_SPONLY);
	pPrice = register_cvar("molotov_price", "4000", FCVAR_SPONLY);
	pMlDamage = register_cvar("molotov_damage", "50.0", FCVAR_SPONLY);
	pMlRadius = register_cvar("molotov_radius", "150.0", FCVAR_SPONLY);
	pFireTime = register_cvar("molotov_firetime", "7", FCVAR_SPONLY);
	pFireDmg = register_cvar("molotov_firedamage", "4", FCVAR_SPONLY);
	pFriendlyFire = register_cvar("molotov_ff", "0", FCVAR_SPONLY);
	pMaxMolotovs = register_cvar("molotov_max", "10", FCVAR_SPONLY);
	pBuyMenu = register_cvar("molotov_inmenu", "0", FCVAR_SPONLY);
	pBuyZone = register_cvar("molotov_buyzone", "1", FCVAR_SPONLY);
	pMolotovMenu = register_cvar("molotov_menu", "0", FCVAR_SPONLY);

	register_event("CurWeapon", "Event_CurWeapon", "be", "1=1");
	register_event("HLTV", "event_new_round", "a", "1=0", "2=0");
	register_event("TextMsg", "Event_GameRestart", "a", "2=#Game_Commencing", "2=#Game_will_restart_in");
	register_event("DeathMsg", "event_DeathMsg", "a");

	register_event("ShowMenu", "event_BuyMenuT", "b", "4=#T_BuyItem", "1=575");
	register_event("ShowMenu", "event_BuyMenuCT", "b", "4=#CT_BuyItem", "1=703");
	register_event("ShowMenu", "event_BuyMenuT", "b", "4=#DT_BuyItem", "1=575");
	register_event("ShowMenu", "event_BuyMenuCT", "b", "4=#DCT_BuyItem", "1=767");

	register_logevent("logevent_Round_End", 2, "1=Round_End");

	register_menucmd(register_menuid("#CT_BuyItem"), 1023, "handle_BuyMenuCT");
	register_menucmd(register_menuid("#T_BuyItem"), 1023, "handle_BuyMenuT");

	register_forward(FM_EmitSound, "fw_EmitSound");

	g_MaxPlayers = get_maxplayers();

	gmsgScoreInfo = get_user_msgid("ScoreInfo");
	gmsgDeathMsg = get_user_msgid("DeathMsg");

	g_pAllocModel = engfunc(EngFunc_AllocString, "models/molotov/p_molotov.mdl");
	g_vAllocModel = engfunc(EngFunc_AllocString, "models/molotov/v_molotov.mdl");

	g_bomb_map = engfunc(EngFunc_FindEntityByString, g_MaxPlayers, "classname", "info_bomb_target") ? 1 : 0;
}

public plugin_precache() {

	firespr = precache_model("sprites/flame.spr");

	smokespr[0] = precache_model("sprites/black_smoke3.spr");
	smokespr[1] = precache_model("sprites/steam1.spr");

	precache_sound("molotov/molotov_fire.wav");

	precache_model("models/molotov/p_molotov.mdl");
	precache_model("models/molotov/v_molotov.mdl");
	precache_model("models/molotov/w_molotov.mdl");
	precache_model("models/molotov/w_broke_molotov.mdl");

}

public client_disconnect(id) {
	g_hasMolotov[id] = 0;
}

public fw_EmitSound(ent, channel, sample[]) {

	if (equal(sample[8], "he_bounce", 9)) {

		new model[32];
		pev(ent, pev_model, model, 31);

		if (equal(model[9], "lotov/w_molotov.mdl")) {
			if (last_Molotov_ent != ent) {
				new Float:fFriction, Float:fVelocity[3];

				pev(ent, pev_friction, fFriction);
				pev(ent, pev_velocity, fVelocity);

				fFriction *= 1.3;	// Increase friction to make it look more realistic
				set_pev(ent, pev_friction, fFriction);
#if defined MOLOTOV_DEBUG
				log_amx("[MC] ent:%d Friction:%f Velocity:%f/%f/%f ====================", ent, fFriction, fVelocity[0], fVelocity[1], fVelocity[2]);
#endif
				last_Molotov_ent = ent;
				grenade_explode(ent);

				return FMRES_SUPERCEDE;
#if defined MOLOTOV_DEBUG
			} else {
				log_amx("[MC] last_Molotov_ent(%d) ent(%d)", last_Molotov_ent, ent);
#endif
			}
		}
	}
	return FMRES_IGNORED;
}

public Event_CurWeapon(id) {

	if (!get_pcvar_num(pEnabled) || !is_user_alive(id)) {
		return PLUGIN_CONTINUE;
	}

	if (!g_hasMolotov[id] && !get_pcvar_num(pOverride)) {
		return PLUGIN_CONTINUE;
	}

	new WeaponID = get_user_weapon(id, WeaponID, WeaponID);

	if (WeaponID != CSW_SMOKEGRENADE) {
		return PLUGIN_CONTINUE;
	}

	set_pev(id, pev_viewmodel, g_vAllocModel);
	set_pev(id, pev_weaponmodel, g_pAllocModel);
	set_pev(id, pev_weaponanim, 9);

	return PLUGIN_CONTINUE;
}

public Event_GameRestart() {
	g_restarted = 1;
}

public event_DeathMsg() {
	g_hasMolotov[read_data(2)] = 0;
}

public logevent_Round_End() {
#if defined MOLOTOV_DEBUG
	log_amx("[MC] ========== Round_End ==========");
#endif
	reset_tasks();
}

stock reset_tasks() {
#if defined MOLOTOV_DEBUG
	new tmpdbgid;
#endif
	for (new i; i < g_MaxPlayers; i++) {
		for (new o; o < MOLOTOV_TASKID_OFFSET; o++) {	//TODO DEBUG: Verify this fixes the tasks not reset at new round issue
			if (task_exists(MOLOTOV_TASKID_BASE1 + (MOLOTOV_TASKID_OFFSET * i) + o)) {
				remove_task(MOLOTOV_TASKID_BASE1 + (MOLOTOV_TASKID_OFFSET * i) + o);
#if defined MOLOTOV_DEBUG
				tmpdbgid = MOLOTOV_TASKID_BASE1 + (MOLOTOV_TASKID_OFFSET * i) + o;
				log_amx("[MC] %d exists. ----------==========----------", tmpdbgid);
#endif
			}

			if (task_exists(MOLOTOV_TASKID_BASE2 + (MOLOTOV_TASKID_OFFSET * i) + o)) {
				remove_task(MOLOTOV_TASKID_BASE2 + (MOLOTOV_TASKID_OFFSET * i) + o);
#if defined MOLOTOV_DEBUG
				tmpdbgid = MOLOTOV_TASKID_BASE2 + (MOLOTOV_TASKID_OFFSET * i) + o;
				log_amx("[MC] %d exists. ----------==========----------", tmpdbgid);
#endif
			}

			if (task_exists(MOLOTOV_TASKID_BASE3 + (MOLOTOV_TASKID_OFFSET * i) + o)) {
				remove_task(MOLOTOV_TASKID_BASE3 + (MOLOTOV_TASKID_OFFSET * i) + o);
#if defined MOLOTOV_DEBUG
				tmpdbgid = MOLOTOV_TASKID_BASE3 + (MOLOTOV_TASKID_OFFSET * i) + o;
				log_amx("[MC] %d exists. ----------==========----------", tmpdbgid);
#endif
			}
		}
	}
}

public event_new_round(id) {
#if defined MOLOTOV_DEBUG
	log_amx("[MC] ========== event_new_round ==========");
#endif
	if (!get_pcvar_num(pEnabled)) {
		return PLUGIN_CONTINUE;
	}

	reset_tasks();	// DEBUG

	if (get_pcvar_num(pMolotovMenu)) {
		show_molotov_menu(id);
	}

	for (new i; i < g_MaxPlayers; i++) {
		if (g_frags[i] && is_user_connected(i)) {
			set_user_frags(i, get_user_frags(i) + g_frags[i]);
		}
		g_frags[i] = 0;
	}

	if (g_restarted) {
		for (new i; i < g_MaxPlayers; i++) {
			g_hasMolotov[i] = 0;
		}
		g_restarted = 0;
	}

	if (get_pcvar_num(pOverride)) {
		set_molotovs();
	} else {
		reset_molotovs();
	}

	return PLUGIN_CONTINUE;
}

public cmd_Override(id, level, cid) {	

	if (!cmd_access(id, level, cid, 1)) {		// First argument (passed to molotov_override) is optional
		return PLUGIN_HANDLED;
	}

	if (!get_pcvar_num(pEnabled)) {
		return PLUGIN_HANDLED;
	}

	if (read_argc() == 1) {				// No arguments; Display status
		client_print(id, print_console, "Override is currently %s.", get_pcvar_num(pOverride) ? "enabled" : "disabled");
		return PLUGIN_HANDLED;
	}

	new arg[2];
	read_argv(1, arg, 1);

	new num = str_to_num(arg);

	if ((num < 0) || (num > 1) || (!isdigit(arg[0]))) {	// If less than 0 or greater than 1 or not a digit
		if (id) {
			client_print(id, print_console, "Invalid argument(%s). Valid arguments are ^"0^" and ^"1^".", arg);
		} else {
			server_print("Invalid argument(%s). Valid arguments are ^"0^" and ^"1^".", arg);
		}
		return PLUGIN_HANDLED;
	}

	if (num == get_pcvar_num(pOverride)) {
		if (id) {
			client_print(id, print_console, "Override is already %s.", num ? "enabled" : "disabled");
		} else {
			server_print("Override is already %s.", num ? "enabled" : "disabled");
		}
		return PLUGIN_HANDLED;
	}

	set_pcvar_num(pOverride, num);

	if (id) {
		client_print(id, print_console, "Override was %s.", num ? "enabled" : "disabled");
	} else {
		server_print("Override was %s.", num ? "enabled" : "disabled");
	}

	if (num) {
		set_molotovs();
	} else {
		reset_molotovs();
	}

	return PLUGIN_HANDLED;
}

public cmd_PluginStatus(id, level, cid) {
	if (!cmd_access(id, level, cid, 1)) {		// First argument (passed to molotov_cocktail) is optional
		return PLUGIN_HANDLED;
	}

	if (read_argc() == 1) {				// No arguments; Display status
		client_print(id, print_console, "Plugin is currently %s.", get_pcvar_num(pEnabled) ? "enabled" : "disabled");
		return PLUGIN_HANDLED;
	}

	new arg[2];
	read_argv(1, arg, 1);

	new num = str_to_num(arg);

	if ((num < 0) || (num > 1) || (!isdigit(arg[0]))) {	// If less than 0 or greater than 1 or not a digit
		if (id) {
			client_print(id, print_console, "Invalid argument(%s). Valid arguments are ^"0^" and ^"1^".", arg);
		} else {
			server_print("Invalid argument(%s). Valid arguments are ^"0^" and ^"1^".", arg);
		}
		return PLUGIN_HANDLED;
	}

	if (num == get_pcvar_num(pEnabled)) {
		if (id) {
			client_print(id, print_console, "Plugin is already %s.", num ? "enabled" : "disabled");
		} else {
			server_print("Plugin is already %s.", num ? "enabled" : "disabled");
		}
		return PLUGIN_HANDLED;
	}

	set_pcvar_num(pEnabled, num);

	if (id) {
		client_print(id, print_console, "Plugin was %s.", num ? "enabled" : "disabled");
	} else {
		server_print("Plugin was %s.", num ? "enabled" : "disabled");
	}

	if (num && get_pcvar_num(pOverride)) {
		set_molotovs();
	} else {
		reset_molotovs();
	}
	return PLUGIN_HANDLED;
}

public cmd_MolotovGive(id, level, cid) {

#if defined MOLOTOV_DEBUG
	log_amx("[MC] cmd_MolotovGive");
#endif
	if (!cmd_access(id, level, cid, 2)) {
		return PLUGIN_HANDLED;
	}

	new Arg1[64], target;
	read_argv(1, Arg1, 63);

	new adminName[32];
	get_user_name(id, adminName, 31);

	new targetTeam, targetTeamName[32];
	new Players[32], iNum;
#if defined MOLOTOV_DEBUG
	log_amx("[MC] cmd_MolotovGive Arg1[0](%s) Arg1[1](%s)", Arg1[0], Arg1[1]);
#endif
	if (Arg1[0] == '@') {

		if (equali(Arg1[1], "all")) {
			targetTeam = 0;
		} else if (equali(Arg1[1], "t") || equali(Arg1[1], "al")) {	// CS_TEAM_T or ALLIES
			targetTeam = TEAM_ONE;
		} else if (equali(Arg1[1], "ct") || equali(Arg1[1], "ax")) {	// CS_TEAM_CT or AXIS
			targetTeam = TEAM_TWO;
		}

		get_players(Players, iNum, "ac");	// Bots don't understand molotov cocktails

		for (new i = 0; i < iNum; ++i) {
			target = Players[i];

			if ((targetTeam == 0) || (get_user_team(target) == targetTeam)) {
				g_hasMolotov[target] = MOLOTOV_HARD_LIMIT;

				give_item(target, "weapon_smokegrenade");
				cs_set_user_bpammo(target, CSW_SMOKEGRENADE, MOLOTOV_HARD_LIMIT);
				emit_sound(target, CHAN_WEAPON, "items/gunpickup2.wav", VOL_NORM, ATTN_NORM, 0, PITCH_NORM);
			}
		}

		switch(targetTeam) {
			case 0: {
				targetTeamName = "everyone";
			}
			case 1: {
				if (cstrike_running()) {
					targetTeamName = "all terrorists";
				} else if (is_running("dod")) {
					targetTeamName = "all allies";
				} else {
					targetTeamName = "team 1";
				}
			}
			case 2: {
				if (cstrike_running()) {
					targetTeamName = "all ct's";
				} else if (is_running("dod")) {
					targetTeamName = "all axis";
				} else {
					targetTeamName = "team 2";
				}
			}
		}
		client_print(0, print_chat, "ADMIN %s: has given %s %d Molotov Cocktails!", adminName, targetTeamName, MOLOTOV_HARD_LIMIT);

	} else {

		target = cmd_target(id, Arg1, 0);

		if (!is_user_connected(target) || !is_user_alive(target)) {
			return PLUGIN_HANDLED;
		}

		new targetName[32];
		get_user_name(target, targetName, 31);

		g_hasMolotov[target] = MOLOTOV_HARD_LIMIT;

		give_item(target, "weapon_smokegrenade");
		cs_set_user_bpammo(target, CSW_SMOKEGRENADE, MOLOTOV_HARD_LIMIT);

		emit_sound(target, CHAN_WEAPON, "items/gunpickup2.wav", VOL_NORM, ATTN_NORM, 0, PITCH_NORM);

		client_print(target, print_chat, "ADMIN %s: has given you %d Molotov Cocktails!", adminName, MOLOTOV_HARD_LIMIT);

	}
	return PLUGIN_HANDLED;
}

public buy_molotov(id) {

	if (!get_pcvar_num(pEnabled)) {
		return PLUGIN_HANDLED;
	}

	if (get_pcvar_num(pOverride)) {
		if (get_pcvar_num(pBuyMenu)) {
			client_print(id, print_center, "Buy them in the buy equipment menu.");
		} else {
			client_print(id, print_center, "Just buy a HE grenade and get molotov automatically!");
		}
		return PLUGIN_HANDLED;
	}

	if (!is_user_alive(id)) {
		client_print(id, print_center, "Sen Molotov Kokteyli Alamassin Cunku Olusun");
		return PLUGIN_HANDLED;
	}

	if (!cs_get_user_buyzone(id) && get_pcvar_num(pBuyZone)==1&&!is_vip(id)) {
		client_print(id, print_center, "Burada Molotov Kokteyli Alamassin.");
		return PLUGIN_HANDLED;
	}

	new money = cs_get_user_money(id);

	if (money < get_pcvar_num(pPrice)) {
		client_print(id, print_center, "Molotov Kokteyli Almak Icin Yeterli Paran Yok");
		return PLUGIN_HANDLED;
	}

	if (g_hasMolotov[id] == get_pcvar_num(pMaxMolotovs)) {
		if (g_hasMolotov[id] == 1&&!is_vip(id)) {
			client_print(id, print_center, "Sen Molotov Kokteyline Sahipsin");
		} else {
			client_print(id, print_center, "Sende %d Molotov Cocktail Var.", g_hasMolotov[id]);
		}
		return PLUGIN_HANDLED;
	}

	if (!g_hasMolotov[id] && user_has_weapon(id, CSW_SMOKEGRENADE)) {
		client_print(id, print_center, "You already have a HE Grenade.");
		return PLUGIN_HANDLED;
	}

	cs_set_user_money(id, money - get_pcvar_num(pPrice));
	give_item(id, "weapon_smokegrenade");
	cs_set_user_bpammo(id, CSW_SMOKEGRENADE, ++g_hasMolotov[id]);
	client_print(id, print_chat, "Sen Molotov Kokteyli Aldin");

	return PLUGIN_HANDLED;
}

public event_BuyMenuCT(id) {

	if (!get_pcvar_num(pEnabled) || !get_pcvar_num(pBuyMenu)) {
		return PLUGIN_CONTINUE;
	}

	new Override = get_pcvar_num(pOverride);

	new menu[1024];
	new len = formatex(menu, 1023, "\yBuy Equipment\R$ Cost");

	len += formatex(menu[len], 1023-len, "^n^n\w1. Kevlar Vest\R\y650");
	len += formatex(menu[len], 1023-len, "^n\w2. Kevlar Vest & Helmet\R\y1000");
	len += formatex(menu[len], 1023-len, "^n\w3. Flashbang\R\y200");

	if (Override) {
		len += formatex(menu[len], 1023-len, "^n\w4. Molotov Cocktail\R\y%d", get_pcvar_num(pPrice));
	} else {
		len += formatex(menu[len], 1023-len, "^n\w4. HE Grenade\R\y300");
	}

	len += formatex(menu[len], 1023-len, "^n\w5. Smoke Grenade\R\y300");
	len += formatex(menu[len], 1023-len, "^n\w6. NightVision Goggles\R\y1250");
	len += formatex(menu[len], 1023-len, "^n\%c7. Defuse Kit\R\y200 ", g_bomb_map ? 'w' : 'd');
	len += formatex(menu[len], 1023-len, "^n\w8. Tactical Shield\R\y2200");

	if (!Override) {
		len += formatex(menu[len], 1023-len, "^n\w9. Molotov Cocktail\R\y%d", get_pcvar_num(pPrice));
	}

	len += formatex(menu[len], 1023-len, "^n^n\w0. Exit");

	show_menu(id, read_data(1)|MENU_KEY_9, menu, -1, "#CT_BuyItem");

	return PLUGIN_HANDLED;
}

public event_BuyMenuT(id) {

	if (!get_pcvar_num(pEnabled) || !get_pcvar_num(pBuyMenu)) {
		return PLUGIN_CONTINUE;
	}

	new Override = get_pcvar_num(pOverride);

	new menu[1024];
	new len = formatex(menu, 1023, "\yBuy Equipment\R$ Cost");
	len += formatex(menu[len], 1023-len, "^n^n\w1. Kevlar Vest\R\y650");
	len += formatex(menu[len], 1023-len, "^n\w2. Kevlar Vest & Helmet\R\y1000");
	len += formatex(menu[len], 1023-len, "^n\w3. Flashbang\R\y200");

	if (Override) {
		len += formatex(menu[len], 1023-len, "^n\w4. Molotov Cocktail\R\y%d", get_pcvar_num(pPrice));
	} else {
		len += formatex(menu[len], 1023-len, "^n\w4. HE Grenade\R\y300");
	}

	len += formatex(menu[len], 1023-len, "^n\w5. Smoke Grenade\R\y300");
	len += formatex(menu[len], 1023-len, "^n\w6. NightVision Goggles\R\y1250");

	if (!Override) {
		len += formatex(menu[len], 1023-len, "^n\w7. Molotov Cocktail\R\y%d", get_pcvar_num(pPrice));
	}

	len += formatex(menu[len], 1023-len, "^n^n\w0. Exit");

	show_menu(id, read_data(1)|MENU_KEY_7, menu, -1, "#T_BuyItem");

	return PLUGIN_HANDLED;
}

public handle_BuyMenuCT(id, key) {

	if (key == (get_pcvar_num(pOverride) ? 3 : 8)) {
		handle_BuyMenu(id);
		return PLUGIN_HANDLED;
	}

	return PLUGIN_CONTINUE;
}

public handle_BuyMenuT(id, key) {

	if (key == (get_pcvar_num(pOverride) ? 3 : 6)) {
		handle_BuyMenu(id);
		return PLUGIN_HANDLED;
	}

	return PLUGIN_CONTINUE;
}

stock handle_BuyMenu(id) {

	new money = cs_get_user_money(id);

	if (money < get_pcvar_num(pPrice)) {
		client_print(id, print_center, "Molotov Kokteyli Alman Icin Yeterli Paran Yok");
		return PLUGIN_HANDLED;
	}

	if (g_hasMolotov[id] == get_pcvar_num(pMaxMolotovs)) {
		if (g_hasMolotov[id] == 1) {
			client_print(id, print_center, "Sen Molotov Kokteyline Sahipsin");
		} else {
			client_print(id, print_center, "Sende %d Molotov Cocktail Var.", g_hasMolotov[id]);
		}
		return PLUGIN_HANDLED;
	} else if (!g_hasMolotov[id] && user_has_weapon(id, CSW_SMOKEGRENADE)) {
		client_print(id, print_center, "You already have a SM Grenade.");
		return PLUGIN_HANDLED;
	}

	cs_set_user_money(id, money - get_pcvar_num(pPrice));
	give_item(id, "weapon_smokegrenade");
	cs_set_user_bpammo(id, CSW_SMOKEGRENADE, ++g_hasMolotov[id]);
	client_print(id, print_chat, "You got a Molotov Cocktail!");

	return PLUGIN_HANDLED;
}

public grenade_throw(id, ent, wid) {

	if (!get_pcvar_num(pEnabled) || !is_user_connected(id) || wid != CSW_SMOKEGRENADE) {
		return PLUGIN_CONTINUE;
	}

	if (!g_hasMolotov[id] && !get_pcvar_num(pOverride)) {
		return PLUGIN_CONTINUE;
	}

	g_hasMolotov[id]--;
	engfunc(EngFunc_SetModel, ent, "models/molotov/w_molotov.mdl");
	set_pev(ent, pev_nextthink, 99999.0);

	return PLUGIN_CONTINUE;
}

public grenade_explode(ent) {

	new param[6], iOrigin[3];
	new Float:fOrigin[3];
	new owner = pev(ent, pev_owner);
	new ent2 = engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, "info_target"));

	pev(ent, pev_origin, fOrigin);

#if defined MOLOTOV_DEBUG
	new iOwnerAlive = is_user_alive(owner);
	new iOwnerConnected = is_user_connected(owner);
	new iEnt2Valid = pev_valid(ent2);
	log_amx("[MC] grenade_explode ent(%d) owner(%d) ent2(%d) iOwnerAlive(%d) iOwnerConnected(%d) iEnt2Valid(%d)", ent, owner, ent2, iOwnerAlive, iOwnerConnected, iEnt2Valid);
#endif

	param[0] = ent;
	param[1] = ent2;
	param[2] = owner;
	param[3] = iOrigin[0] = floatround(fOrigin[0]);
	param[4] = iOrigin[1] = floatround(fOrigin[1]);
	param[5] = iOrigin[2] = floatround(fOrigin[2]);

	emit_sound(ent, CHAN_AUTO, "molotov/molotov_fire.wav", VOL_NORM, ATTN_NORM, 0, PITCH_NORM);

	engfunc(EngFunc_SetModel, ent, "models/molotov/w_broke_molotov.mdl");

	random_fire(iOrigin, ent2);
	radius_damage(owner, fOrigin, get_pcvar_float(pMlDamage), get_pcvar_float(pMlRadius), DMG_BLAST);

	new Float:FireTime = get_pcvar_float(pFireTime);

	if (++g_Molotov_offset[owner] == MOLOTOV_HARD_LIMIT) {
		g_Molotov_offset[owner] = 0;
	}

	set_task(0.2, "fire_damage", MOLOTOV_TASKID_BASE1 + (MOLOTOV_TASKID_OFFSET * (owner - 1)) + g_Molotov_offset[owner], param, 6, "a", floatround(FireTime / 0.2, floatround_floor));
	set_task(1.0, "fire_sound", MOLOTOV_TASKID_BASE2 + (MOLOTOV_TASKID_OFFSET * (owner - 1)) + g_Molotov_offset[owner], param, 6, "a", floatround(FireTime) - 1);
	set_task(FireTime, "fire_stop", MOLOTOV_TASKID_BASE3 + (MOLOTOV_TASKID_OFFSET * (owner - 1)) + g_Molotov_offset[owner], param, 6);

	return PLUGIN_CONTINUE;
}

public fire_sound(param[]) {
	emit_sound(param[1], CHAN_AUTO, "molotov/molotov_fire.wav", VOL_NORM, ATTN_NORM, 0, PITCH_NORM);
}

public fire_stop(param[]) {
	g_g = 0;

	if (pev_valid(param[0])) { engfunc(EngFunc_RemoveEntity, param[0]); }
	if (pev_valid(param[1])) { engfunc(EngFunc_RemoveEntity, param[1]); }

	if ((last_Molotov_ent = (param[0]))) {
		last_Molotov_ent = 0;
	}
}

public fire_damage(param[]) {

	new iOrigin[3], Float:fOrigin[3];
	iOrigin[0] = param[3];
	iOrigin[1] = param[4];
	iOrigin[2] = param[5];

	random_fire(iOrigin, param[1]);

	IVecFVec(iOrigin, fOrigin);
	radius_damage(param[2], fOrigin, get_pcvar_float(pFireDmg), get_pcvar_float(pMlRadius), DMG_BURN, 0);
}

stock radius_damage(attacker, Float:origin[3], Float:damage, Float:range, dmgtype, calc = 1) {

	new Float:pOrigin[3], Float:dist, Float:tmpdmg;
	new i, ateam = get_user_team(attacker), iFF = get_pcvar_num(pFriendlyFire);

	while (i++ < g_MaxPlayers) {
		if (!is_user_alive(i)) {
			continue;
		}

		if (!iFF && ateam == get_user_team(i)) {
			continue;
		}

		pev(i, pev_origin, pOrigin);
		dist = get_distance_f(origin, pOrigin);

		if (dist > range) {
			continue;
		}

		if (calc) {
			tmpdmg = damage - (damage / range) * dist;
		} else {
			tmpdmg = damage;
		}

		if (pev(i, pev_health) < tmpdmg) {
			kill(attacker, i);
		} else {
			fm_fakedamage(i, "molotov", tmpdmg, dmgtype);
		}
	}

	while ((i = engfunc(EngFunc_FindEntityInSphere, i, origin, range))) {	// warning 211: possibly unintended assignment
		if (pev(i, pev_takedamage)) {
			if (calc) {
				pev(i, pev_origin, pOrigin);
				tmpdmg = damage - (damage / range) * get_distance_f(origin, pOrigin);
			} else {
				tmpdmg = damage;
			}
			fm_fakedamage(i, "molotov", tmpdmg, dmgtype);
		}
	}
}

stock random_fire(Origin[3], ent) {

	new range = get_pcvar_num(pMlRadius);
	new iOrigin[3];

	for (new i = 1; i <= 5; i++) {

		g_g = 1;

		iOrigin[0] = Origin[0] + random_num(-range, range);
		iOrigin[1] = Origin[1] + random_num(-range, range);
		iOrigin[2] = Origin[2];
		iOrigin[2] = ground_z(iOrigin, ent);

		while (get_distance(iOrigin, Origin) > range) {
			g_g++;
#if defined MOLOTOV_DEBUG
			//log_amx("[MC] random_fire ent(%d) i(%d) g_g(%d)", ent, i, g_g);
#endif
			iOrigin[0] = Origin[0] + random_num(-range, range);
			iOrigin[1] = Origin[1] + random_num(-range, range);
			iOrigin[2] = Origin[2];

			if (g_g >= ANTI_LAGG) {
				iOrigin[2] = ground_z(iOrigin, ent, 1);
			} else {
				iOrigin[2] = ground_z(iOrigin, ent);
			}
		}

		new rand = random_num(5, 15);

		message_begin(MSG_BROADCAST, SVC_TEMPENTITY);
		write_byte(TE_SPRITE);
		write_coord(iOrigin[0]);
		write_coord(iOrigin[1]);
		write_coord(iOrigin[2] + rand * 5);
		write_short(firespr);
		write_byte(rand);
		write_byte(100);
		message_end();

		if (!(i % 4)) {	// Smoke every 4th flame
			message_begin(MSG_BROADCAST, SVC_TEMPENTITY);
			write_byte(TE_SMOKE);
			write_coord(iOrigin[0]);
			write_coord(iOrigin[1]);
			write_coord(iOrigin[2] + 120);
			write_short(smokespr[random_num(0, 1)]);
			write_byte(random_num(10, 30));
			write_byte(random_num(10, 20));
			message_end();
		}
	}
}

stock kill(k, v) {

	user_silentkill(v);

	new kteam = get_user_team(k);
	new vteam = get_user_team(v);

	new kfrags = get_user_frags(k) + 1;
	new kdeaths = get_user_deaths(k);
	if (kteam == vteam) {
		kfrags = get_user_frags(k) - 2;
	}

	new vfrags = get_user_frags(v);
	new vdeaths = get_user_deaths(v);

	message_begin(MSG_ALL, gmsgScoreInfo);
	write_byte(k);
	write_short(kfrags);
	write_short(kdeaths);
	write_short(0);
	write_short(kteam);
	message_end();

	message_begin(MSG_ALL, gmsgScoreInfo);
	write_byte(v);
	write_short(vfrags + 1);
	write_short(vdeaths);
	write_short(0);
	write_short(vteam);
	message_end();

	message_begin(MSG_ALL, gmsgDeathMsg, {0,0,0}, 0);
	write_byte(k);
	write_byte(v);
	write_byte(0);
	write_string("molotov");
	message_end();

	g_frags[k]++;

	if (kteam != vteam) {
		cs_set_user_money(k, cs_get_user_money(k) + 300);
	} else {
		cs_set_user_money(k, cs_get_user_money(k) - 300);
	}
}

stock ground_z(iOrigin[3], ent, skip = 0, iRecursion = 0) {

#if defined MOLOTOV_DEBUG
	new iEntValid = pev_valid(ent);
	if (iRecursion > 0) {
		log_amx("[MC] ground_z ent(%d) iEntValid(%d) skip(%d) iRecursion(%d)", ent, iEntValid, skip, iRecursion);
	}
#endif
	iOrigin[2] += random_num(5, 80);

	if (!pev_valid(ent)) {	// Fix for: Run time error 10: native error (native "set_pev")
		return iOrigin[2];
	}

	new Float:fOrigin[3];

	IVecFVec(iOrigin, fOrigin);

	set_pev(ent, pev_origin, fOrigin);

	engfunc(EngFunc_DropToFloor, ent);

	if (!skip && !engfunc(EngFunc_EntIsOnFloor, ent)) {
		if (iRecursion >= ANTI_LAGG) {
			skip = 1;
		}
#if defined MOLOTOV_DEBUG
		log_amx("[MC] ground_z ++iRecursion(%d)", ++iRecursion);
		return ground_z(iOrigin, ent, skip, iRecursion);
#else
		return ground_z(iOrigin, ent, skip, ++iRecursion);
#endif
	}

	pev(ent, pev_origin, fOrigin);

	return floatround(fOrigin[2]);
}

stock reset_molotovs() {
	new ent = g_MaxPlayers;
	while ((ent = engfunc(EngFunc_FindEntityByString, ent, "model", "models/molotov/w_molotov.mdl"))) {
		engfunc(EngFunc_SetModel, ent, "models/w_smokegrenade.mdl");
	}
}

stock set_molotovs() {
	new ent = g_MaxPlayers;
	while ((ent = engfunc(EngFunc_FindEntityByString, ent, "model", "models/w_smokegrenade.mdl"))) {
		engfunc(EngFunc_SetModel, ent, "models/molotov/w_molotov.mdl");
	}
}

// This will run at event New Round if enabled
public show_molotov_menu(id) {
	new menu[192];

	// Get a custom menu title with the price
	// When done it should look something like this:
	// Buy Molotov Cocktail ($1200)...
	new menu_title_text[120], the_molotov_price[7];
	get_cvar_string("molotov_price", the_molotov_price, 6);
	strcat(menu_title_text, "Buy Molotov Cocktail ($", 40);
	strcat(menu_title_text, the_molotov_price, 40);
	strcat(menu_title_text, ")?^n^n1. Yes, I will burn them all...^n2. No, I will kill in some other way...^n^n0. EXIT MENU", 119);

	format(menu, 191, menu_title_text);

	// This shows the menu for 30 seconds, I tried first with get_cvar_num("mp_buytime")*60 , but it didn't work well
	// when using 0.5 as mp_buytime. If you like, just change the time below
	show_menu(id, MOLOTOV_MENU_KEYS, menu, 30);

	return PLUGIN_HANDLED;
}

//Our menu function will get the player id and the key they pressed
public giveMolotov(id, key) {

	//key will start at zero
	if (key == 0) {
		buy_molotov(id);
	} else if (key == 1) {
		client_print(id, print_center, ">You have chosen not to buy a Molotov Coctail<");
	} else {
		client_print(id, print_center, ">You have choosen to exit the molotov menu...<");
	}
}
Pentru ajutor, faceți cerere bine detaliată, completând și respectând modelul corespunzător.
Nu-mi mai dați cereri doar pentru a mă avea în lista de prieteni.
Dacă te ajut, și mă ignori/etc > te adaug în „foe”.
Aveți grijă la cei ce încearcă să mă copieze sau să dea drept mine..Puteți lua legătura cu mine prin STEAM dacă aveți o problemă/nelămurire în acest caz! Cont de forum am doar aici.
În cazul în care utilizați ceva din ce am postat(ex: aici), e bine să fiți la curent cu modificările aduse și de aici, iar dacă sunt ceva probleme nu ezitați să luați legătura cu mine. Actualizarea unor coduri nu se vor afișa public, doar dacă se găsește ceva critic/urgent de remediat, unele fiind coduri vechi iar unele refăcute chiar recent dar private.
* Nume pe cs1.6: eVoLuTiOn \ Nume vechi: eVo
* Atelierul meu - post2819572.html#p2819572 (închis, click link ca să vedeți de ce)
diavolu111
Membru, skill +1
Membru, skill +1
Posts: 419
Joined: 11 Oct 2014, 18:18
Detinator Steam: Da
Fond eXtream: 0
Location: Alba Iulia
Has thanked: 28 times
Been thanked: 6 times
Contact:

10 Mar 2020, 22:40

Daca scrii /molotov in chat acum intra in loc la smoke, dar nu se intampla nimic. Modelul este de la molotov, dar cand arunci molotovul si ajunge jos nu se intampla nimic, ramane doar modelul pe jos. Iti las niste imagini sa iti dai seama mai bine ce vreau sa spun: https://imgur.com/a/wQMELCk

Si ca vip poti sa cumperi cate grenade molotov vrei. Se poate pune un maxim de 3 ori sa cumperi? Daca da, te rog sa pui asa si sa imi spui si de unde pot modifica numarul de grenade pentru VIP in caz ca am nevoie :)

Multumesc.
User avatar
levin
Scripter eXtreamCS
Scripter eXtreamCS
Posts: 3844
Joined: 24 Aug 2011, 12:24
Detinator Steam: Da
CS Status:
Detinator server CS: ☯∴
SteamID: riseofevo
Reputatie: Scripter eXtreamCS
Nume anterior: Adryyy
Location: ҳ̸Ҳ̸ҳ
Discord: devilclass
Has thanked: 36 times
Been thanked: 594 times
Contact:

11 Mar 2020, 19:24

Code: Select all

/*******************************************************************************
			Molotov Cocktail
			  Version 3.20
		Maintained by: DynamicBits (Andy)

* Commands:
- say molotov - Buy a molotov
- say /molotov - Buy a molotov
- molotov_give <player|@all|@t|@ct|@al|@ax> - Gives molotovs to a player, a team, or everyone
- molotov_cocktail [0|1] - Enable/disable the plugin (If no arguments, show the status)
- molotov_override [0|1] - Enable/disable the HE grenade override (If no arguments, show the status)

* Cvars
- molotov_enabled - Enable/disable the plugin [1 = enabled; 0 = disabled] [default = 1]
- molotov_price - Set the molotov price [default = 1200]
- molotov_damage - Set the damage done by initial molotov explosion [default = 50.0]
- molotov_radius - Set the radius of molotov damage [default = 150.0]
- molotov_firetime - Duration (in seconds) of fire effects, sounds, etc. [default = 6]
- molotov_firedamage - Amount of damage done by fire effects (every 0.2 secs). [default = 3]
- molotov_ff - Disable(0)/enable(1) the ability to damage/kill someone on your team with molotov. [default = 1] (Was molotov_tk)
- molotov_override_he - Override the original hegrenade automaticly with molotov. [default = 0] (Was molotov_tempoverride)
- molotov_max - Max num of molotovs able to carry. [default = 1] (Does not work with override)
- molotov_inmenu - Puts molotov in the end of the equipment buymenu (old menu, not VGUI). [default = 0]
		   (If the override cvar is enabled the hegrenade will be replaced instead.)
- molotov_buyzone - Do you have to be in buyzone? [default = 1] (If molotov_inmenu=1, this is ignored)
- molotov_menu - Enables menu at beginning of each round [default = 0] (Was amx_molotovmenu)

* Required Modules:
- Fakemeta
- Fun
- Cstrike
- CSX

* Changelog/Credit:
- DynamicBits
  * Version 3.20 (2008-11-20)
    - My first public release
    - Finally tracked down and fixed the intermittent crashing problem (I hope!)
    - Modified default damage values
    - molotov_cocktail/molotov_override commands now change settings *or* display status
    - Broken molotov model stays closer to the explosion (looks more realistic)
    - Task IDs are now guaranteed to be unique
    - Modified anti-lag calculations to be more accurate (less likely to lag)
    - Changed amx_molotovmenu CVAR to molotov_menu
    - Changed molotov_tk CVAR to molotov_ff
    - Changed molotov_tempoverride CVAR to molotov_override_he
    - Preparation for support of mods other than Counter-Strike
    - Fixed lots of coding mistakes
    - Optimized several sections of code
    - Corrected grammar/typos
    - Clean up code (Removed unused code/unhelpful comments, fixed formatting, and semicolons!)
- Raffe (CantShoot)
  * (Unversioned release)
    - Originally fixed plugin to run on Linux servers
    - Added optional menu to purchase molotov cocktails each round
    - Moved models and sounds into proper molotov/ subdirectories
    - Fixed molotovs not being reset upon player disconnect
    - (Almost) fixed molotovs not being removed for new round
    - Added @all/@ct/@t arguments to cmd_MolotovGive
    - Changed some models/sound
- [ --<-@ ] Black Rose
  * Version 3.0-3.1c ?
    - Unknown changes
- SAMURAI
  * Original plugin author


*/

#include <amxmodx>
#include <amxmisc>
#include <fakemeta>
#include <cstrike>
#include <csx>
#include <fun>
#include <fakemeta_util>

#define vip_flag "t"
#define is_vip(%1)	(get_user_flags(%1)&read_flags(vip_flag))
#define MAXIM_GRENADE_VIP 3

// Uncomment the following line to enable debug logging.
//#define MOLOTOV_DEBUG

#define AUTHORS "DynamicBits"

#define ADMIN_ACCESS ADMIN_KICK

#define ANTI_LAGG 7.0	// Defines max calculations before a flame is spawned without check if onground
// This is to prevent lagg at really narrow ents where you could end up with 400 calculations per flame
// Suggested: <= 10

#define MOLOTOV_HARD_LIMIT 10	// Maximum molotov cocktails this code is capable of handling without bugs
				// Also how many cocktails people get with molotov_give command

#define MOLOTOV_MENU_KEYS MENU_KEY_0|MENU_KEY_1|MENU_KEY_2	// Choices to look for with optional menu

#define MOLOTOV_TASKID_BASE 1000				// What is the lowest task ID?
#define MOLOTOV_TASKID_OFFSET MOLOTOV_HARD_LIMIT
#define MOLOTOV_TASKID_BASE1 MOLOTOV_TASKID_BASE				 // By default, with 32 players, task ids
#define MOLOTOV_TASKID_BASE2 MOLOTOV_TASKID_BASE1 + (MOLOTOV_TASKID_OFFSET * 32) // from 1000 to 1959 can
#define MOLOTOV_TASKID_BASE3 MOLOTOV_TASKID_BASE2 + (MOLOTOV_TASKID_OFFSET * 32) // potentially be used used.

#define TEAM_UNASSIGNED 0
#define TEAM_ONE	1
#define TEAM_TWO	2
#define TEAM_SPECTATOR	3

new pEnabled, pPrice, pMlDamage, pMlRadius, pFireTime, pOverride;
new pFriendlyFire, pFireDmg, pMaxMolotovs, pBuyMenu, pBuyZone, pMolotovMenu;

new gmsgScoreInfo, gmsgDeathMsg;

new g_pAllocModel, g_vAllocModel;

new g_frags[33];
new g_hasMolotov[33];
new g_restarted;
new g_MaxPlayers;
new g_bomb_map;

new firespr, smokespr[2];

new last_Molotov_ent;
new g_Molotov_offset[33];

new g_g;

public plugin_init() {

	register_plugin("Molotov Cocktail", "3.20", AUTHORS);

	register_menucmd(register_menuid("Buy Molotov Coctail"), MOLOTOV_MENU_KEYS, "giveMolotov");
#if defined MOLOTOV_DEBUG
	register_clcmd("molotov_menutest", "show_molotov_menu");
#endif

	register_clcmd("say /molotov", "buy_molotov");

	register_concmd("molotov_give", "cmd_MolotovGive", ADMIN_ACCESS, "<player|@all|@t|@ct|@al|@ax> - Gives free molotov cocktails (default=10)");
	register_concmd("molotov_override", "cmd_Override", ADMIN_ACCESS, "[0|1] - Enable/disable the HE grenade override (If no arguments, show the status)");
	register_concmd("molotov_cocktail", "cmd_PluginStatus", ADMIN_ACCESS, "[0|1] - Enable/disable the plugin (If no arguments, show the status)");

	pEnabled = register_cvar("molotov_enabled", "1", FCVAR_SPONLY);
	pOverride = register_cvar("molotov_override_he", "0", FCVAR_SPONLY);
	pPrice = register_cvar("molotov_price", "4000", FCVAR_SPONLY);
	pMlDamage = register_cvar("molotov_damage", "50.0", FCVAR_SPONLY);
	pMlRadius = register_cvar("molotov_radius", "150.0", FCVAR_SPONLY);
	pFireTime = register_cvar("molotov_firetime", "7", FCVAR_SPONLY);
	pFireDmg = register_cvar("molotov_firedamage", "4", FCVAR_SPONLY);
	pFriendlyFire = register_cvar("molotov_ff", "0", FCVAR_SPONLY);
	pMaxMolotovs = register_cvar("molotov_max", "10", FCVAR_SPONLY);
	pBuyMenu = register_cvar("molotov_inmenu", "0", FCVAR_SPONLY);
	pBuyZone = register_cvar("molotov_buyzone", "1", FCVAR_SPONLY);
	pMolotovMenu = register_cvar("molotov_menu", "0", FCVAR_SPONLY);

	register_event("CurWeapon", "Event_CurWeapon", "be", "1=1");
	register_event("HLTV", "event_new_round", "a", "1=0", "2=0");
	register_event("TextMsg", "Event_GameRestart", "a", "2=#Game_Commencing", "2=#Game_will_restart_in");
	register_event("DeathMsg", "event_DeathMsg", "a");

	register_event("ShowMenu", "event_BuyMenuT", "b", "4=#T_BuyItem", "1=575");
	register_event("ShowMenu", "event_BuyMenuCT", "b", "4=#CT_BuyItem", "1=703");
	register_event("ShowMenu", "event_BuyMenuT", "b", "4=#DT_BuyItem", "1=575");
	register_event("ShowMenu", "event_BuyMenuCT", "b", "4=#DCT_BuyItem", "1=767");

	register_logevent("logevent_Round_End", 2, "1=Round_End");

	register_menucmd(register_menuid("#CT_BuyItem"), 1023, "handle_BuyMenuCT");
	register_menucmd(register_menuid("#T_BuyItem"), 1023, "handle_BuyMenuT");

	register_forward(FM_EmitSound, "fw_EmitSound");

	g_MaxPlayers = get_maxplayers();

	gmsgScoreInfo = get_user_msgid("ScoreInfo");
	gmsgDeathMsg = get_user_msgid("DeathMsg");

	g_pAllocModel = engfunc(EngFunc_AllocString, "models/molotov/p_molotov.mdl");
	g_vAllocModel = engfunc(EngFunc_AllocString, "models/molotov/v_molotov.mdl");

	g_bomb_map = engfunc(EngFunc_FindEntityByString, g_MaxPlayers, "classname", "info_bomb_target") ? 1 : 0;
}

public plugin_precache() {

	firespr = precache_model("sprites/flame.spr");

	smokespr[0] = precache_model("sprites/black_smoke3.spr");
	smokespr[1] = precache_model("sprites/steam1.spr");

	precache_sound("molotov/molotov_fire.wav");

	precache_model("models/molotov/p_molotov.mdl");
	precache_model("models/molotov/v_molotov.mdl");
	precache_model("models/molotov/w_molotov.mdl");
	precache_model("models/molotov/w_broke_molotov.mdl");

}

public client_disconnect(id) {
	g_hasMolotov[id] = 0;
}

public fw_EmitSound(ent, channel, sample[]) {

	if (equal(sample[9], "sg_explode", 10)) {

		new model[32];
		pev(ent, pev_model, model, 31);

		if (equal(model[9], "lotov/w_molotov.mdl")) {
			if (last_Molotov_ent != ent) {
				new Float:fFriction, Float:fVelocity[3];

				pev(ent, pev_friction, fFriction);
				pev(ent, pev_velocity, fVelocity);

				fFriction *= 1.3;	// Increase friction to make it look more realistic
				set_pev(ent, pev_friction, fFriction);
#if defined MOLOTOV_DEBUG
				log_amx("[MC] ent:%d Friction:%f Velocity:%f/%f/%f ====================", ent, fFriction, fVelocity[0], fVelocity[1], fVelocity[2]);
#endif
				last_Molotov_ent = ent;
				grenade_explode(ent);

				return FMRES_SUPERCEDE;
#if defined MOLOTOV_DEBUG
			} else {
				log_amx("[MC] last_Molotov_ent(%d) ent(%d)", last_Molotov_ent, ent);
#endif
			}
		}
	}
	return FMRES_IGNORED;
}

public Event_CurWeapon(id) {

	if (!get_pcvar_num(pEnabled) || !is_user_alive(id)) {
		return PLUGIN_CONTINUE;
	}

	if (!g_hasMolotov[id] && !get_pcvar_num(pOverride)) {
		return PLUGIN_CONTINUE;
	}

	new WeaponID = get_user_weapon(id, WeaponID, WeaponID);

	if (WeaponID != CSW_SMOKEGRENADE) {
		return PLUGIN_CONTINUE;
	}

	set_pev(id, pev_viewmodel, g_vAllocModel);
	set_pev(id, pev_weaponmodel, g_pAllocModel);
	set_pev(id, pev_weaponanim, 9);

	return PLUGIN_CONTINUE;
}

public Event_GameRestart() {
	g_restarted = 1;
}

public event_DeathMsg() {
	g_hasMolotov[read_data(2)] = 0;
}

public logevent_Round_End() {
#if defined MOLOTOV_DEBUG
	log_amx("[MC] ========== Round_End ==========");
#endif
	reset_tasks();
}

stock reset_tasks() {
#if defined MOLOTOV_DEBUG
	new tmpdbgid;
#endif
	for (new i; i < g_MaxPlayers; i++) {
		for (new o; o < MOLOTOV_TASKID_OFFSET; o++) {	//TODO DEBUG: Verify this fixes the tasks not reset at new round issue
			if (task_exists(MOLOTOV_TASKID_BASE1 + (MOLOTOV_TASKID_OFFSET * i) + o)) {
				remove_task(MOLOTOV_TASKID_BASE1 + (MOLOTOV_TASKID_OFFSET * i) + o);
#if defined MOLOTOV_DEBUG
				tmpdbgid = MOLOTOV_TASKID_BASE1 + (MOLOTOV_TASKID_OFFSET * i) + o;
				log_amx("[MC] %d exists. ----------==========----------", tmpdbgid);
#endif
			}

			if (task_exists(MOLOTOV_TASKID_BASE2 + (MOLOTOV_TASKID_OFFSET * i) + o)) {
				remove_task(MOLOTOV_TASKID_BASE2 + (MOLOTOV_TASKID_OFFSET * i) + o);
#if defined MOLOTOV_DEBUG
				tmpdbgid = MOLOTOV_TASKID_BASE2 + (MOLOTOV_TASKID_OFFSET * i) + o;
				log_amx("[MC] %d exists. ----------==========----------", tmpdbgid);
#endif
			}

			if (task_exists(MOLOTOV_TASKID_BASE3 + (MOLOTOV_TASKID_OFFSET * i) + o)) {
				remove_task(MOLOTOV_TASKID_BASE3 + (MOLOTOV_TASKID_OFFSET * i) + o);
#if defined MOLOTOV_DEBUG
				tmpdbgid = MOLOTOV_TASKID_BASE3 + (MOLOTOV_TASKID_OFFSET * i) + o;
				log_amx("[MC] %d exists. ----------==========----------", tmpdbgid);
#endif
			}
		}
	}
}

public event_new_round(id) {
#if defined MOLOTOV_DEBUG
	log_amx("[MC] ========== event_new_round ==========");
#endif
	if (!get_pcvar_num(pEnabled)) {
		return PLUGIN_CONTINUE;
	}

	reset_tasks();	// DEBUG

	if (get_pcvar_num(pMolotovMenu)) {
		show_molotov_menu(id);
	}

	for (new i; i < g_MaxPlayers; i++) {
		if (g_frags[i] && is_user_connected(i)) {
			set_user_frags(i, get_user_frags(i) + g_frags[i]);
		}
		g_frags[i] = 0;
	}

	if (g_restarted) {
		for (new i; i < g_MaxPlayers; i++) {
			g_hasMolotov[i] = 0;
		}
		g_restarted = 0;
	}

	if (get_pcvar_num(pOverride)) {
		set_molotovs();
	} else {
		reset_molotovs();
	}

	return PLUGIN_CONTINUE;
}

public cmd_Override(id, level, cid) {	

	if (!cmd_access(id, level, cid, 1)) {		// First argument (passed to molotov_override) is optional
		return PLUGIN_HANDLED;
	}

	if (!get_pcvar_num(pEnabled)) {
		return PLUGIN_HANDLED;
	}

	if (read_argc() == 1) {				// No arguments; Display status
		client_print(id, print_console, "Override is currently %s.", get_pcvar_num(pOverride) ? "enabled" : "disabled");
		return PLUGIN_HANDLED;
	}

	new arg[2];
	read_argv(1, arg, 1);

	new num = str_to_num(arg);

	if ((num < 0) || (num > 1) || (!isdigit(arg[0]))) {	// If less than 0 or greater than 1 or not a digit
		if (id) {
			client_print(id, print_console, "Invalid argument(%s). Valid arguments are ^"0^" and ^"1^".", arg);
		} else {
			server_print("Invalid argument(%s). Valid arguments are ^"0^" and ^"1^".", arg);
		}
		return PLUGIN_HANDLED;
	}

	if (num == get_pcvar_num(pOverride)) {
		if (id) {
			client_print(id, print_console, "Override is already %s.", num ? "enabled" : "disabled");
		} else {
			server_print("Override is already %s.", num ? "enabled" : "disabled");
		}
		return PLUGIN_HANDLED;
	}

	set_pcvar_num(pOverride, num);

	if (id) {
		client_print(id, print_console, "Override was %s.", num ? "enabled" : "disabled");
	} else {
		server_print("Override was %s.", num ? "enabled" : "disabled");
	}

	if (num) {
		set_molotovs();
	} else {
		reset_molotovs();
	}

	return PLUGIN_HANDLED;
}

public cmd_PluginStatus(id, level, cid) {
	if (!cmd_access(id, level, cid, 1)) {		// First argument (passed to molotov_cocktail) is optional
		return PLUGIN_HANDLED;
	}

	if (read_argc() == 1) {				// No arguments; Display status
		client_print(id, print_console, "Plugin is currently %s.", get_pcvar_num(pEnabled) ? "enabled" : "disabled");
		return PLUGIN_HANDLED;
	}

	new arg[2];
	read_argv(1, arg, 1);

	new num = str_to_num(arg);

	if ((num < 0) || (num > 1) || (!isdigit(arg[0]))) {	// If less than 0 or greater than 1 or not a digit
		if (id) {
			client_print(id, print_console, "Invalid argument(%s). Valid arguments are ^"0^" and ^"1^".", arg);
		} else {
			server_print("Invalid argument(%s). Valid arguments are ^"0^" and ^"1^".", arg);
		}
		return PLUGIN_HANDLED;
	}

	if (num == get_pcvar_num(pEnabled)) {
		if (id) {
			client_print(id, print_console, "Plugin is already %s.", num ? "enabled" : "disabled");
		} else {
			server_print("Plugin is already %s.", num ? "enabled" : "disabled");
		}
		return PLUGIN_HANDLED;
	}

	set_pcvar_num(pEnabled, num);

	if (id) {
		client_print(id, print_console, "Plugin was %s.", num ? "enabled" : "disabled");
	} else {
		server_print("Plugin was %s.", num ? "enabled" : "disabled");
	}

	if (num && get_pcvar_num(pOverride)) {
		set_molotovs();
	} else {
		reset_molotovs();
	}
	return PLUGIN_HANDLED;
}

public cmd_MolotovGive(id, level, cid) {

#if defined MOLOTOV_DEBUG
	log_amx("[MC] cmd_MolotovGive");
#endif
	if (!cmd_access(id, level, cid, 2)) {
		return PLUGIN_HANDLED;
	}

	new Arg1[64], target;
	read_argv(1, Arg1, 63);

	new adminName[32];
	get_user_name(id, adminName, 31);

	new targetTeam, targetTeamName[32];
	new Players[32], iNum;
#if defined MOLOTOV_DEBUG
	log_amx("[MC] cmd_MolotovGive Arg1[0](%s) Arg1[1](%s)", Arg1[0], Arg1[1]);
#endif
	if (Arg1[0] == '@') {

		if (equali(Arg1[1], "all")) {
			targetTeam = 0;
		} else if (equali(Arg1[1], "t") || equali(Arg1[1], "al")) {	// CS_TEAM_T or ALLIES
			targetTeam = TEAM_ONE;
		} else if (equali(Arg1[1], "ct") || equali(Arg1[1], "ax")) {	// CS_TEAM_CT or AXIS
			targetTeam = TEAM_TWO;
		}

		get_players(Players, iNum, "ac");	// Bots don't understand molotov cocktails

		for (new i = 0; i < iNum; ++i) {
			target = Players[i];

			if ((targetTeam == 0) || (get_user_team(target) == targetTeam)) {
				g_hasMolotov[target] = MOLOTOV_HARD_LIMIT;

				give_item(target, "weapon_smokegrenade");
				cs_set_user_bpammo(target, CSW_SMOKEGRENADE, MOLOTOV_HARD_LIMIT);
				emit_sound(target, CHAN_WEAPON, "items/gunpickup2.wav", VOL_NORM, ATTN_NORM, 0, PITCH_NORM);
			}
		}

		switch(targetTeam) {
			case 0: {
				targetTeamName = "everyone";
			}
			case 1: {
				if (cstrike_running()) {
					targetTeamName = "all terrorists";
				} else if (is_running("dod")) {
					targetTeamName = "all allies";
				} else {
					targetTeamName = "team 1";
				}
			}
			case 2: {
				if (cstrike_running()) {
					targetTeamName = "all ct's";
				} else if (is_running("dod")) {
					targetTeamName = "all axis";
				} else {
					targetTeamName = "team 2";
				}
			}
		}
		client_print(0, print_chat, "ADMIN %s: has given %s %d Molotov Cocktails!", adminName, targetTeamName, MOLOTOV_HARD_LIMIT);

	} else {

		target = cmd_target(id, Arg1, 0);

		if (!is_user_connected(target) || !is_user_alive(target)) {
			return PLUGIN_HANDLED;
		}

		new targetName[32];
		get_user_name(target, targetName, 31);

		g_hasMolotov[target] = MOLOTOV_HARD_LIMIT;

		give_item(target, "weapon_smokegrenade");
		cs_set_user_bpammo(target, CSW_SMOKEGRENADE, MOLOTOV_HARD_LIMIT);

		emit_sound(target, CHAN_WEAPON, "items/gunpickup2.wav", VOL_NORM, ATTN_NORM, 0, PITCH_NORM);

		client_print(target, print_chat, "ADMIN %s: has given you %d Molotov Cocktails!", adminName, MOLOTOV_HARD_LIMIT);

	}
	return PLUGIN_HANDLED;
}

public buy_molotov(id) {

	if (!get_pcvar_num(pEnabled)) {
		return PLUGIN_HANDLED;
	}

	if (get_pcvar_num(pOverride)) {
		if (get_pcvar_num(pBuyMenu)) {
			client_print(id, print_center, "Buy them in the buy equipment menu.");
		} else {
			client_print(id, print_center, "Just buy a HE grenade and get molotov automatically!");
		}
		return PLUGIN_HANDLED;
	}

	if (!is_user_alive(id)) {
		client_print(id, print_center, "Sen Molotov Kokteyli Alamassin Cunku Olusun");
		return PLUGIN_HANDLED;
	}

	if (!cs_get_user_buyzone(id) && get_pcvar_num(pBuyZone)==1&&!is_vip(id)) {
		client_print(id, print_center, "Burada Molotov Kokteyli Alamassin.");
		return PLUGIN_HANDLED;
	}

	new money = cs_get_user_money(id);

	if (money < get_pcvar_num(pPrice)) {
		client_print(id, print_center, "Molotov Kokteyli Almak Icin Yeterli Paran Yok");
		return PLUGIN_HANDLED;
	}

	if (g_hasMolotov[id] == get_pcvar_num(pMaxMolotovs)&&!is_vip(id)) {
		if (g_hasMolotov[id] == 1) {
			client_print(id, print_center, "Sen Molotov Kokteyline Sahipsin");
		} else {
			client_print(id, print_center, "Sende %d Molotov Cocktail Var.", g_hasMolotov[id]);
		}
		return PLUGIN_HANDLED;
	}
	if(g_hasMolotiv[id]==MAXIM_GRENADE_VIP&&is_vip(id))
	{
		client_print(id, print_center, "Ai atins maximum de molotiv VIP!");
		return PLUGIN_HANDLED
	}

	if (!g_hasMolotov[id] && user_has_weapon(id, CSW_SMOKEGRENADE)) {
		client_print(id, print_center, "You already have a HE Grenade.");
		return PLUGIN_HANDLED;
	}

	cs_set_user_money(id, money - get_pcvar_num(pPrice));
	give_item(id, "weapon_smokegrenade");
	cs_set_user_bpammo(id, CSW_SMOKEGRENADE, ++g_hasMolotov[id]);
	client_print(id, print_chat, "Sen Molotov Kokteyli Aldin");

	return PLUGIN_HANDLED;
}

public event_BuyMenuCT(id) {

	if (!get_pcvar_num(pEnabled) || !get_pcvar_num(pBuyMenu)) {
		return PLUGIN_CONTINUE;
	}

	new Override = get_pcvar_num(pOverride);

	new menu[1024];
	new len = formatex(menu, 1023, "\yBuy Equipment\R$ Cost");

	len += formatex(menu[len], 1023-len, "^n^n\w1. Kevlar Vest\R\y650");
	len += formatex(menu[len], 1023-len, "^n\w2. Kevlar Vest & Helmet\R\y1000");
	len += formatex(menu[len], 1023-len, "^n\w3. Flashbang\R\y200");

	if (Override) {
		len += formatex(menu[len], 1023-len, "^n\w4. Molotov Cocktail\R\y%d", get_pcvar_num(pPrice));
	} else {
		len += formatex(menu[len], 1023-len, "^n\w4. HE Grenade\R\y300");
	}

	len += formatex(menu[len], 1023-len, "^n\w5. Smoke Grenade\R\y300");
	len += formatex(menu[len], 1023-len, "^n\w6. NightVision Goggles\R\y1250");
	len += formatex(menu[len], 1023-len, "^n\%c7. Defuse Kit\R\y200 ", g_bomb_map ? 'w' : 'd');
	len += formatex(menu[len], 1023-len, "^n\w8. Tactical Shield\R\y2200");

	if (!Override) {
		len += formatex(menu[len], 1023-len, "^n\w9. Molotov Cocktail\R\y%d", get_pcvar_num(pPrice));
	}

	len += formatex(menu[len], 1023-len, "^n^n\w0. Exit");

	show_menu(id, read_data(1)|MENU_KEY_9, menu, -1, "#CT_BuyItem");

	return PLUGIN_HANDLED;
}

public event_BuyMenuT(id) {

	if (!get_pcvar_num(pEnabled) || !get_pcvar_num(pBuyMenu)) {
		return PLUGIN_CONTINUE;
	}

	new Override = get_pcvar_num(pOverride);

	new menu[1024];
	new len = formatex(menu, 1023, "\yBuy Equipment\R$ Cost");
	len += formatex(menu[len], 1023-len, "^n^n\w1. Kevlar Vest\R\y650");
	len += formatex(menu[len], 1023-len, "^n\w2. Kevlar Vest & Helmet\R\y1000");
	len += formatex(menu[len], 1023-len, "^n\w3. Flashbang\R\y200");

	if (Override) {
		len += formatex(menu[len], 1023-len, "^n\w4. Molotov Cocktail\R\y%d", get_pcvar_num(pPrice));
	} else {
		len += formatex(menu[len], 1023-len, "^n\w4. HE Grenade\R\y300");
	}

	len += formatex(menu[len], 1023-len, "^n\w5. Smoke Grenade\R\y300");
	len += formatex(menu[len], 1023-len, "^n\w6. NightVision Goggles\R\y1250");

	if (!Override) {
		len += formatex(menu[len], 1023-len, "^n\w7. Molotov Cocktail\R\y%d", get_pcvar_num(pPrice));
	}

	len += formatex(menu[len], 1023-len, "^n^n\w0. Exit");

	show_menu(id, read_data(1)|MENU_KEY_7, menu, -1, "#T_BuyItem");

	return PLUGIN_HANDLED;
}

public handle_BuyMenuCT(id, key) {

	if (key == (get_pcvar_num(pOverride) ? 3 : 8)) {
		handle_BuyMenu(id);
		return PLUGIN_HANDLED;
	}

	return PLUGIN_CONTINUE;
}

public handle_BuyMenuT(id, key) {

	if (key == (get_pcvar_num(pOverride) ? 3 : 6)) {
		handle_BuyMenu(id);
		return PLUGIN_HANDLED;
	}

	return PLUGIN_CONTINUE;
}

stock handle_BuyMenu(id) {

	new money = cs_get_user_money(id);

	if (money < get_pcvar_num(pPrice)) {
		client_print(id, print_center, "Molotov Kokteyli Alman Icin Yeterli Paran Yok");
		return PLUGIN_HANDLED;
	}

	if (g_hasMolotov[id] == get_pcvar_num(pMaxMolotovs)) {
		if (g_hasMolotov[id] == 1) {
			client_print(id, print_center, "Sen Molotov Kokteyline Sahipsin");
		} else {
			client_print(id, print_center, "Sende %d Molotov Cocktail Var.", g_hasMolotov[id]);
		}
		return PLUGIN_HANDLED;
	} else if (!g_hasMolotov[id] && user_has_weapon(id, CSW_SMOKEGRENADE)) {
		client_print(id, print_center, "You already have a SM Grenade.");
		return PLUGIN_HANDLED;
	}

	cs_set_user_money(id, money - get_pcvar_num(pPrice));
	give_item(id, "weapon_smokegrenade");
	cs_set_user_bpammo(id, CSW_SMOKEGRENADE, ++g_hasMolotov[id]);
	client_print(id, print_chat, "You got a Molotov Cocktail!");

	return PLUGIN_HANDLED;
}

public grenade_throw(id, ent, wid) {

	if (!get_pcvar_num(pEnabled) || !is_user_connected(id) || wid != CSW_SMOKEGRENADE) {
		return PLUGIN_CONTINUE;
	}

	if (!g_hasMolotov[id] && !get_pcvar_num(pOverride)) {
		return PLUGIN_CONTINUE;
	}

	g_hasMolotov[id]--;
	engfunc(EngFunc_SetModel, ent, "models/molotov/w_molotov.mdl");
	set_pev(ent, pev_nextthink, 99999.0);

	return PLUGIN_CONTINUE;
}

public grenade_explode(ent) {

	new param[6], iOrigin[3];
	new Float:fOrigin[3];
	new owner = pev(ent, pev_owner);
	new ent2 = engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, "info_target"));

	pev(ent, pev_origin, fOrigin);

#if defined MOLOTOV_DEBUG
	new iOwnerAlive = is_user_alive(owner);
	new iOwnerConnected = is_user_connected(owner);
	new iEnt2Valid = pev_valid(ent2);
	log_amx("[MC] grenade_explode ent(%d) owner(%d) ent2(%d) iOwnerAlive(%d) iOwnerConnected(%d) iEnt2Valid(%d)", ent, owner, ent2, iOwnerAlive, iOwnerConnected, iEnt2Valid);
#endif

	param[0] = ent;
	param[1] = ent2;
	param[2] = owner;
	param[3] = iOrigin[0] = floatround(fOrigin[0]);
	param[4] = iOrigin[1] = floatround(fOrigin[1]);
	param[5] = iOrigin[2] = floatround(fOrigin[2]);

	emit_sound(ent, CHAN_AUTO, "molotov/molotov_fire.wav", VOL_NORM, ATTN_NORM, 0, PITCH_NORM);

	engfunc(EngFunc_SetModel, ent, "models/molotov/w_broke_molotov.mdl");

	random_fire(iOrigin, ent2);
	radius_damage(owner, fOrigin, get_pcvar_float(pMlDamage), get_pcvar_float(pMlRadius), DMG_BLAST);

	new Float:FireTime = get_pcvar_float(pFireTime);

	if (++g_Molotov_offset[owner] == MOLOTOV_HARD_LIMIT) {
		g_Molotov_offset[owner] = 0;
	}

	set_task(0.2, "fire_damage", MOLOTOV_TASKID_BASE1 + (MOLOTOV_TASKID_OFFSET * (owner - 1)) + g_Molotov_offset[owner], param, 6, "a", floatround(FireTime / 0.2, floatround_floor));
	set_task(1.0, "fire_sound", MOLOTOV_TASKID_BASE2 + (MOLOTOV_TASKID_OFFSET * (owner - 1)) + g_Molotov_offset[owner], param, 6, "a", floatround(FireTime) - 1);
	set_task(FireTime, "fire_stop", MOLOTOV_TASKID_BASE3 + (MOLOTOV_TASKID_OFFSET * (owner - 1)) + g_Molotov_offset[owner], param, 6);

	return PLUGIN_CONTINUE;
}

public fire_sound(param[]) {
	emit_sound(param[1], CHAN_AUTO, "molotov/molotov_fire.wav", VOL_NORM, ATTN_NORM, 0, PITCH_NORM);
}

public fire_stop(param[]) {
	g_g = 0;

	if (pev_valid(param[0])) { engfunc(EngFunc_RemoveEntity, param[0]); }
	if (pev_valid(param[1])) { engfunc(EngFunc_RemoveEntity, param[1]); }

	if ((last_Molotov_ent = (param[0]))) {
		last_Molotov_ent = 0;
	}
}

public fire_damage(param[]) {

	new iOrigin[3], Float:fOrigin[3];
	iOrigin[0] = param[3];
	iOrigin[1] = param[4];
	iOrigin[2] = param[5];

	random_fire(iOrigin, param[1]);

	IVecFVec(iOrigin, fOrigin);
	radius_damage(param[2], fOrigin, get_pcvar_float(pFireDmg), get_pcvar_float(pMlRadius), DMG_BURN, 0);
}

stock radius_damage(attacker, Float:origin[3], Float:damage, Float:range, dmgtype, calc = 1) {

	new Float:pOrigin[3], Float:dist, Float:tmpdmg;
	new i, ateam = get_user_team(attacker), iFF = get_pcvar_num(pFriendlyFire);

	while (i++ < g_MaxPlayers) {
		if (!is_user_alive(i)) {
			continue;
		}

		if (!iFF && ateam == get_user_team(i)) {
			continue;
		}

		pev(i, pev_origin, pOrigin);
		dist = get_distance_f(origin, pOrigin);

		if (dist > range) {
			continue;
		}

		if (calc) {
			tmpdmg = damage - (damage / range) * dist;
		} else {
			tmpdmg = damage;
		}

		if (pev(i, pev_health) < tmpdmg) {
			kill(attacker, i);
		} else {
			fm_fakedamage(i, "molotov", tmpdmg, dmgtype);
		}
	}

	while ((i = engfunc(EngFunc_FindEntityInSphere, i, origin, range))) {	// warning 211: possibly unintended assignment
		if (pev(i, pev_takedamage)) {
			if (calc) {
				pev(i, pev_origin, pOrigin);
				tmpdmg = damage - (damage / range) * get_distance_f(origin, pOrigin);
			} else {
				tmpdmg = damage;
			}
			fm_fakedamage(i, "molotov", tmpdmg, dmgtype);
		}
	}
}

stock random_fire(Origin[3], ent) {

	new range = get_pcvar_num(pMlRadius);
	new iOrigin[3];

	for (new i = 1; i <= 5; i++) {

		g_g = 1;

		iOrigin[0] = Origin[0] + random_num(-range, range);
		iOrigin[1] = Origin[1] + random_num(-range, range);
		iOrigin[2] = Origin[2];
		iOrigin[2] = ground_z(iOrigin, ent);

		while (get_distance(iOrigin, Origin) > range) {
			g_g++;
#if defined MOLOTOV_DEBUG
			//log_amx("[MC] random_fire ent(%d) i(%d) g_g(%d)", ent, i, g_g);
#endif
			iOrigin[0] = Origin[0] + random_num(-range, range);
			iOrigin[1] = Origin[1] + random_num(-range, range);
			iOrigin[2] = Origin[2];

			if (g_g >= ANTI_LAGG) {
				iOrigin[2] = ground_z(iOrigin, ent, 1);
			} else {
				iOrigin[2] = ground_z(iOrigin, ent);
			}
		}

		new rand = random_num(5, 15);

		message_begin(MSG_BROADCAST, SVC_TEMPENTITY);
		write_byte(TE_SPRITE);
		write_coord(iOrigin[0]);
		write_coord(iOrigin[1]);
		write_coord(iOrigin[2] + rand * 5);
		write_short(firespr);
		write_byte(rand);
		write_byte(100);
		message_end();

		if (!(i % 4)) {	// Smoke every 4th flame
			message_begin(MSG_BROADCAST, SVC_TEMPENTITY);
			write_byte(TE_SMOKE);
			write_coord(iOrigin[0]);
			write_coord(iOrigin[1]);
			write_coord(iOrigin[2] + 120);
			write_short(smokespr[random_num(0, 1)]);
			write_byte(random_num(10, 30));
			write_byte(random_num(10, 20));
			message_end();
		}
	}
}

stock kill(k, v) {

	user_silentkill(v);

	new kteam = get_user_team(k);
	new vteam = get_user_team(v);

	new kfrags = get_user_frags(k) + 1;
	new kdeaths = get_user_deaths(k);
	if (kteam == vteam) {
		kfrags = get_user_frags(k) - 2;
	}

	new vfrags = get_user_frags(v);
	new vdeaths = get_user_deaths(v);

	message_begin(MSG_ALL, gmsgScoreInfo);
	write_byte(k);
	write_short(kfrags);
	write_short(kdeaths);
	write_short(0);
	write_short(kteam);
	message_end();

	message_begin(MSG_ALL, gmsgScoreInfo);
	write_byte(v);
	write_short(vfrags + 1);
	write_short(vdeaths);
	write_short(0);
	write_short(vteam);
	message_end();

	message_begin(MSG_ALL, gmsgDeathMsg, {0,0,0}, 0);
	write_byte(k);
	write_byte(v);
	write_byte(0);
	write_string("molotov");
	message_end();

	g_frags[k]++;

	if (kteam != vteam) {
		cs_set_user_money(k, cs_get_user_money(k) + 300);
	} else {
		cs_set_user_money(k, cs_get_user_money(k) - 300);
	}
}

stock ground_z(iOrigin[3], ent, skip = 0, iRecursion = 0) {

#if defined MOLOTOV_DEBUG
	new iEntValid = pev_valid(ent);
	if (iRecursion > 0) {
		log_amx("[MC] ground_z ent(%d) iEntValid(%d) skip(%d) iRecursion(%d)", ent, iEntValid, skip, iRecursion);
	}
#endif
	iOrigin[2] += random_num(5, 80);

	if (!pev_valid(ent)) {	// Fix for: Run time error 10: native error (native "set_pev")
		return iOrigin[2];
	}

	new Float:fOrigin[3];

	IVecFVec(iOrigin, fOrigin);

	set_pev(ent, pev_origin, fOrigin);

	engfunc(EngFunc_DropToFloor, ent);

	if (!skip && !engfunc(EngFunc_EntIsOnFloor, ent)) {
		if (iRecursion >= ANTI_LAGG) {
			skip = 1;
		}
#if defined MOLOTOV_DEBUG
		log_amx("[MC] ground_z ++iRecursion(%d)", ++iRecursion);
		return ground_z(iOrigin, ent, skip, iRecursion);
#else
		return ground_z(iOrigin, ent, skip, ++iRecursion);
#endif
	}

	pev(ent, pev_origin, fOrigin);

	return floatround(fOrigin[2]);
}

stock reset_molotovs() {
	new ent = g_MaxPlayers;
	while ((ent = engfunc(EngFunc_FindEntityByString, ent, "model", "models/molotov/w_molotov.mdl"))) {
		engfunc(EngFunc_SetModel, ent, "models/w_smokegrenade.mdl");
	}
}

stock set_molotovs() {
	new ent = g_MaxPlayers;
	while ((ent = engfunc(EngFunc_FindEntityByString, ent, "model", "models/w_smokegrenade.mdl"))) {
		engfunc(EngFunc_SetModel, ent, "models/molotov/w_molotov.mdl");
	}
}

// This will run at event New Round if enabled
public show_molotov_menu(id) {
	new menu[192];

	// Get a custom menu title with the price
	// When done it should look something like this:
	// Buy Molotov Cocktail ($1200)...
	new menu_title_text[120], the_molotov_price[7];
	get_cvar_string("molotov_price", the_molotov_price, 6);
	strcat(menu_title_text, "Buy Molotov Cocktail ($", 40);
	strcat(menu_title_text, the_molotov_price, 40);
	strcat(menu_title_text, ")?^n^n1. Yes, I will burn them all...^n2. No, I will kill in some other way...^n^n0. EXIT MENU", 119);

	format(menu, 191, menu_title_text);

	// This shows the menu for 30 seconds, I tried first with get_cvar_num("mp_buytime")*60 , but it didn't work well
	// when using 0.5 as mp_buytime. If you like, just change the time below
	show_menu(id, MOLOTOV_MENU_KEYS, menu, 30);

	return PLUGIN_HANDLED;
}

//Our menu function will get the player id and the key they pressed
public giveMolotov(id, key) {

	//key will start at zero
	if (key == 0) {
		buy_molotov(id);
	} else if (key == 1) {
		client_print(id, print_center, ">You have chosen not to buy a Molotov Coctail<");
	} else {
		client_print(id, print_center, ">You have choosen to exit the molotov menu...<");
	}
}
Pentru ajutor, faceți cerere bine detaliată, completând și respectând modelul corespunzător.
Nu-mi mai dați cereri doar pentru a mă avea în lista de prieteni.
Dacă te ajut, și mă ignori/etc > te adaug în „foe”.
Aveți grijă la cei ce încearcă să mă copieze sau să dea drept mine..Puteți lua legătura cu mine prin STEAM dacă aveți o problemă/nelămurire în acest caz! Cont de forum am doar aici.
În cazul în care utilizați ceva din ce am postat(ex: aici), e bine să fiți la curent cu modificările aduse și de aici, iar dacă sunt ceva probleme nu ezitați să luați legătura cu mine. Actualizarea unor coduri nu se vor afișa public, doar dacă se găsește ceva critic/urgent de remediat, unele fiind coduri vechi iar unele refăcute chiar recent dar private.
* Nume pe cs1.6: eVoLuTiOn \ Nume vechi: eVo
* Atelierul meu - post2819572.html#p2819572 (închis, click link ca să vedeți de ce)
diavolu111
Membru, skill +1
Membru, skill +1
Posts: 419
Joined: 11 Oct 2014, 18:18
Detinator Steam: Da
Fond eXtream: 0
Location: Alba Iulia
Has thanked: 28 times
Been thanked: 6 times
Contact:

11 Mar 2020, 21:47

la vip e ok, acum sunt limitati la 3 molotovuri, dar in rest e la fel... dai cu grenada molotov si ramane modelul de grenada pe jos
User avatar
levin
Scripter eXtreamCS
Scripter eXtreamCS
Posts: 3844
Joined: 24 Aug 2011, 12:24
Detinator Steam: Da
CS Status:
Detinator server CS: ☯∴
SteamID: riseofevo
Reputatie: Scripter eXtreamCS
Nume anterior: Adryyy
Location: ҳ̸Ҳ̸ҳ
Discord: devilclass
Has thanked: 36 times
Been thanked: 594 times
Contact:

11 Mar 2020, 22:44

Code: Select all

/*******************************************************************************
			Molotov Cocktail
			  Version 3.20
		Maintained by: DynamicBits (Andy)

* Commands:
- say molotov - Buy a molotov
- say /molotov - Buy a molotov
- molotov_give <player|@all|@t|@ct|@al|@ax> - Gives molotovs to a player, a team, or everyone
- molotov_cocktail [0|1] - Enable/disable the plugin (If no arguments, show the status)
- molotov_override [0|1] - Enable/disable the HE grenade override (If no arguments, show the status)

* Cvars
- molotov_enabled - Enable/disable the plugin [1 = enabled; 0 = disabled] [default = 1]
- molotov_price - Set the molotov price [default = 1200]
- molotov_damage - Set the damage done by initial molotov explosion [default = 50.0]
- molotov_radius - Set the radius of molotov damage [default = 150.0]
- molotov_firetime - Duration (in seconds) of fire effects, sounds, etc. [default = 6]
- molotov_firedamage - Amount of damage done by fire effects (every 0.2 secs). [default = 3]
- molotov_ff - Disable(0)/enable(1) the ability to damage/kill someone on your team with molotov. [default = 1] (Was molotov_tk)
- molotov_override_he - Override the original hegrenade automaticly with molotov. [default = 0] (Was molotov_tempoverride)
- molotov_max - Max num of molotovs able to carry. [default = 1] (Does not work with override)
- molotov_inmenu - Puts molotov in the end of the equipment buymenu (old menu, not VGUI). [default = 0]
		   (If the override cvar is enabled the hegrenade will be replaced instead.)
- molotov_buyzone - Do you have to be in buyzone? [default = 1] (If molotov_inmenu=1, this is ignored)
- molotov_menu - Enables menu at beginning of each round [default = 0] (Was amx_molotovmenu)

* Required Modules:
- Fakemeta
- Fun
- Cstrike
- CSX

* Changelog/Credit:
- DynamicBits
  * Version 3.20 (2008-11-20)
    - My first public release
    - Finally tracked down and fixed the intermittent crashing problem (I hope!)
    - Modified default damage values
    - molotov_cocktail/molotov_override commands now change settings *or* display status
    - Broken molotov model stays closer to the explosion (looks more realistic)
    - Task IDs are now guaranteed to be unique
    - Modified anti-lag calculations to be more accurate (less likely to lag)
    - Changed amx_molotovmenu CVAR to molotov_menu
    - Changed molotov_tk CVAR to molotov_ff
    - Changed molotov_tempoverride CVAR to molotov_override_he
    - Preparation for support of mods other than Counter-Strike
    - Fixed lots of coding mistakes
    - Optimized several sections of code
    - Corrected grammar/typos
    - Clean up code (Removed unused code/unhelpful comments, fixed formatting, and semicolons!)
- Raffe (CantShoot)
  * (Unversioned release)
    - Originally fixed plugin to run on Linux servers
    - Added optional menu to purchase molotov cocktails each round
    - Moved models and sounds into proper molotov/ subdirectories
    - Fixed molotovs not being reset upon player disconnect
    - (Almost) fixed molotovs not being removed for new round
    - Added @all/@ct/@t arguments to cmd_MolotovGive
    - Changed some models/sound
- [ --<-@ ] Black Rose
  * Version 3.0-3.1c ?
    - Unknown changes
- SAMURAI
  * Original plugin author


*/

#include <amxmodx>
#include <amxmisc>
#include <fakemeta>
#include <cstrike>
#include <csx>
#include <fun>
#include <fakemeta_util>

#define vip_flag "t"
#define is_vip(%1)	(get_user_flags(%1)&read_flags(vip_flag))
#define MAXIM_GRENADE_VIP 3

// Uncomment the following line to enable debug logging.
//#define MOLOTOV_DEBUG

#define AUTHORS "DynamicBits"

#define ADMIN_ACCESS ADMIN_KICK

#define ANTI_LAGG 7.0	// Defines max calculations before a flame is spawned without check if onground
// This is to prevent lagg at really narrow ents where you could end up with 400 calculations per flame
// Suggested: <= 10

#define MOLOTOV_HARD_LIMIT 10	// Maximum molotov cocktails this code is capable of handling without bugs
				// Also how many cocktails people get with molotov_give command

#define MOLOTOV_MENU_KEYS MENU_KEY_0|MENU_KEY_1|MENU_KEY_2	// Choices to look for with optional menu

#define MOLOTOV_TASKID_BASE 1000				// What is the lowest task ID?
#define MOLOTOV_TASKID_OFFSET MOLOTOV_HARD_LIMIT
#define MOLOTOV_TASKID_BASE1 MOLOTOV_TASKID_BASE				 // By default, with 32 players, task ids
#define MOLOTOV_TASKID_BASE2 MOLOTOV_TASKID_BASE1 + (MOLOTOV_TASKID_OFFSET * 32) // from 1000 to 1959 can
#define MOLOTOV_TASKID_BASE3 MOLOTOV_TASKID_BASE2 + (MOLOTOV_TASKID_OFFSET * 32) // potentially be used used.

#define TEAM_UNASSIGNED 0
#define TEAM_ONE	1
#define TEAM_TWO	2
#define TEAM_SPECTATOR	3

new pEnabled, pPrice, pMlDamage, pMlRadius, pFireTime, pOverride;
new pFriendlyFire, pFireDmg, pMaxMolotovs, pBuyMenu, pBuyZone, pMolotovMenu;

new gmsgScoreInfo, gmsgDeathMsg;

new g_pAllocModel, g_vAllocModel;

new g_frags[33];
new g_hasMolotov[33];
new g_restarted;
new g_MaxPlayers;
new g_bomb_map;

new firespr, smokespr[2];

new last_Molotov_ent;
new g_Molotov_offset[33];

new g_g;

public plugin_init() {

	register_plugin("Molotov Cocktail", "3.20", AUTHORS);

	register_menucmd(register_menuid("Buy Molotov Coctail"), MOLOTOV_MENU_KEYS, "giveMolotov");
#if defined MOLOTOV_DEBUG
	register_clcmd("molotov_menutest", "show_molotov_menu");
#endif

	register_clcmd("say /molotov", "buy_molotov");

	register_concmd("molotov_give", "cmd_MolotovGive", ADMIN_ACCESS, "<player|@all|@t|@ct|@al|@ax> - Gives free molotov cocktails (default=10)");
	register_concmd("molotov_override", "cmd_Override", ADMIN_ACCESS, "[0|1] - Enable/disable the HE grenade override (If no arguments, show the status)");
	register_concmd("molotov_cocktail", "cmd_PluginStatus", ADMIN_ACCESS, "[0|1] - Enable/disable the plugin (If no arguments, show the status)");

	pEnabled = register_cvar("molotov_enabled", "1", FCVAR_SPONLY);
	pOverride = register_cvar("molotov_override_he", "0", FCVAR_SPONLY);
	pPrice = register_cvar("molotov_price", "4000", FCVAR_SPONLY);
	pMlDamage = register_cvar("molotov_damage", "50.0", FCVAR_SPONLY);
	pMlRadius = register_cvar("molotov_radius", "150.0", FCVAR_SPONLY);
	pFireTime = register_cvar("molotov_firetime", "7", FCVAR_SPONLY);
	pFireDmg = register_cvar("molotov_firedamage", "4", FCVAR_SPONLY);
	pFriendlyFire = register_cvar("molotov_ff", "0", FCVAR_SPONLY);
	pMaxMolotovs = register_cvar("molotov_max", "10", FCVAR_SPONLY);
	pBuyMenu = register_cvar("molotov_inmenu", "0", FCVAR_SPONLY);
	pBuyZone = register_cvar("molotov_buyzone", "1", FCVAR_SPONLY);
	pMolotovMenu = register_cvar("molotov_menu", "0", FCVAR_SPONLY);

	register_event("CurWeapon", "Event_CurWeapon", "be", "1=1");
	register_event("HLTV", "event_new_round", "a", "1=0", "2=0");
	register_event("TextMsg", "Event_GameRestart", "a", "2=#Game_Commencing", "2=#Game_will_restart_in");
	register_event("DeathMsg", "event_DeathMsg", "a");

	register_event("ShowMenu", "event_BuyMenuT", "b", "4=#T_BuyItem", "1=575");
	register_event("ShowMenu", "event_BuyMenuCT", "b", "4=#CT_BuyItem", "1=703");
	register_event("ShowMenu", "event_BuyMenuT", "b", "4=#DT_BuyItem", "1=575");
	register_event("ShowMenu", "event_BuyMenuCT", "b", "4=#DCT_BuyItem", "1=767");

	register_logevent("logevent_Round_End", 2, "1=Round_End");

	register_menucmd(register_menuid("#CT_BuyItem"), 1023, "handle_BuyMenuCT");
	register_menucmd(register_menuid("#T_BuyItem"), 1023, "handle_BuyMenuT");

	register_forward(FM_EmitSound, "fw_EmitSound");

	g_MaxPlayers = get_maxplayers();

	gmsgScoreInfo = get_user_msgid("ScoreInfo");
	gmsgDeathMsg = get_user_msgid("DeathMsg");

	g_pAllocModel = engfunc(EngFunc_AllocString, "models/molotov/p_molotov.mdl");
	g_vAllocModel = engfunc(EngFunc_AllocString, "models/molotov/v_molotov.mdl");

	g_bomb_map = engfunc(EngFunc_FindEntityByString, g_MaxPlayers, "classname", "info_bomb_target") ? 1 : 0;
}

public plugin_precache() {

	firespr = precache_model("sprites/flame.spr");

	smokespr[0] = precache_model("sprites/black_smoke3.spr");
	smokespr[1] = precache_model("sprites/steam1.spr");

	precache_sound("molotov/molotov_fire.wav");

	precache_model("models/molotov/p_molotov.mdl");
	precache_model("models/molotov/v_molotov.mdl");
	precache_model("models/molotov/w_molotov.mdl");
	precache_model("models/molotov/w_broke_molotov.mdl");

}

public client_disconnect(id) {
	g_hasMolotov[id] = 0;
}

public fw_EmitSound(ent, channel, sample[]) {

	if (equali(sample, "weapons/sg_explode.wav")) {

		new model[32];
		pev(ent, pev_model, model, 31);

		if (equal(model[9], "lotov/w_molotov.mdl")) {
			if (last_Molotov_ent != ent) {
				new Float:fFriction, Float:fVelocity[3];

				pev(ent, pev_friction, fFriction);
				pev(ent, pev_velocity, fVelocity);

				fFriction *= 1.3;	// Increase friction to make it look more realistic
				set_pev(ent, pev_friction, fFriction);
#if defined MOLOTOV_DEBUG
				log_amx("[MC] ent:%d Friction:%f Velocity:%f/%f/%f ====================", ent, fFriction, fVelocity[0], fVelocity[1], fVelocity[2]);
#endif
				last_Molotov_ent = ent;
				grenade_explode(ent);

				return FMRES_SUPERCEDE;
#if defined MOLOTOV_DEBUG
			} else {
				log_amx("[MC] last_Molotov_ent(%d) ent(%d)", last_Molotov_ent, ent);
#endif
			}
		}
	}
	return FMRES_IGNORED;
}

public Event_CurWeapon(id) {

	if (!get_pcvar_num(pEnabled) || !is_user_alive(id)) {
		return PLUGIN_CONTINUE;
	}

	if (!g_hasMolotov[id] && !get_pcvar_num(pOverride)) {
		return PLUGIN_CONTINUE;
	}

	new WeaponID = get_user_weapon(id, WeaponID, WeaponID);

	if (WeaponID != CSW_SMOKEGRENADE) {
		return PLUGIN_CONTINUE;
	}

	set_pev(id, pev_viewmodel, g_vAllocModel);
	set_pev(id, pev_weaponmodel, g_pAllocModel);
	set_pev(id, pev_weaponanim, 9);

	return PLUGIN_CONTINUE;
}

public Event_GameRestart() {
	g_restarted = 1;
}

public event_DeathMsg() {
	g_hasMolotov[read_data(2)] = 0;
}

public logevent_Round_End() {
#if defined MOLOTOV_DEBUG
	log_amx("[MC] ========== Round_End ==========");
#endif
	reset_tasks();
}

stock reset_tasks() {
#if defined MOLOTOV_DEBUG
	new tmpdbgid;
#endif
	for (new i; i < g_MaxPlayers; i++) {
		for (new o; o < MOLOTOV_TASKID_OFFSET; o++) {	//TODO DEBUG: Verify this fixes the tasks not reset at new round issue
			if (task_exists(MOLOTOV_TASKID_BASE1 + (MOLOTOV_TASKID_OFFSET * i) + o)) {
				remove_task(MOLOTOV_TASKID_BASE1 + (MOLOTOV_TASKID_OFFSET * i) + o);
#if defined MOLOTOV_DEBUG
				tmpdbgid = MOLOTOV_TASKID_BASE1 + (MOLOTOV_TASKID_OFFSET * i) + o;
				log_amx("[MC] %d exists. ----------==========----------", tmpdbgid);
#endif
			}

			if (task_exists(MOLOTOV_TASKID_BASE2 + (MOLOTOV_TASKID_OFFSET * i) + o)) {
				remove_task(MOLOTOV_TASKID_BASE2 + (MOLOTOV_TASKID_OFFSET * i) + o);
#if defined MOLOTOV_DEBUG
				tmpdbgid = MOLOTOV_TASKID_BASE2 + (MOLOTOV_TASKID_OFFSET * i) + o;
				log_amx("[MC] %d exists. ----------==========----------", tmpdbgid);
#endif
			}

			if (task_exists(MOLOTOV_TASKID_BASE3 + (MOLOTOV_TASKID_OFFSET * i) + o)) {
				remove_task(MOLOTOV_TASKID_BASE3 + (MOLOTOV_TASKID_OFFSET * i) + o);
#if defined MOLOTOV_DEBUG
				tmpdbgid = MOLOTOV_TASKID_BASE3 + (MOLOTOV_TASKID_OFFSET * i) + o;
				log_amx("[MC] %d exists. ----------==========----------", tmpdbgid);
#endif
			}
		}
	}
}

public event_new_round(id) {
#if defined MOLOTOV_DEBUG
	log_amx("[MC] ========== event_new_round ==========");
#endif
	if (!get_pcvar_num(pEnabled)) {
		return PLUGIN_CONTINUE;
	}

	reset_tasks();	// DEBUG

	if (get_pcvar_num(pMolotovMenu)) {
		show_molotov_menu(id);
	}

	for (new i; i < g_MaxPlayers; i++) {
		if (g_frags[i] && is_user_connected(i)) {
			set_user_frags(i, get_user_frags(i) + g_frags[i]);
		}
		g_frags[i] = 0;
	}

	if (g_restarted) {
		for (new i; i < g_MaxPlayers; i++) {
			g_hasMolotov[i] = 0;
		}
		g_restarted = 0;
	}

	if (get_pcvar_num(pOverride)) {
		set_molotovs();
	} else {
		reset_molotovs();
	}

	return PLUGIN_CONTINUE;
}

public cmd_Override(id, level, cid) {	

	if (!cmd_access(id, level, cid, 1)) {		// First argument (passed to molotov_override) is optional
		return PLUGIN_HANDLED;
	}

	if (!get_pcvar_num(pEnabled)) {
		return PLUGIN_HANDLED;
	}

	if (read_argc() == 1) {				// No arguments; Display status
		client_print(id, print_console, "Override is currently %s.", get_pcvar_num(pOverride) ? "enabled" : "disabled");
		return PLUGIN_HANDLED;
	}

	new arg[2];
	read_argv(1, arg, 1);

	new num = str_to_num(arg);

	if ((num < 0) || (num > 1) || (!isdigit(arg[0]))) {	// If less than 0 or greater than 1 or not a digit
		if (id) {
			client_print(id, print_console, "Invalid argument(%s). Valid arguments are ^"0^" and ^"1^".", arg);
		} else {
			server_print("Invalid argument(%s). Valid arguments are ^"0^" and ^"1^".", arg);
		}
		return PLUGIN_HANDLED;
	}

	if (num == get_pcvar_num(pOverride)) {
		if (id) {
			client_print(id, print_console, "Override is already %s.", num ? "enabled" : "disabled");
		} else {
			server_print("Override is already %s.", num ? "enabled" : "disabled");
		}
		return PLUGIN_HANDLED;
	}

	set_pcvar_num(pOverride, num);

	if (id) {
		client_print(id, print_console, "Override was %s.", num ? "enabled" : "disabled");
	} else {
		server_print("Override was %s.", num ? "enabled" : "disabled");
	}

	if (num) {
		set_molotovs();
	} else {
		reset_molotovs();
	}

	return PLUGIN_HANDLED;
}

public cmd_PluginStatus(id, level, cid) {
	if (!cmd_access(id, level, cid, 1)) {		// First argument (passed to molotov_cocktail) is optional
		return PLUGIN_HANDLED;
	}

	if (read_argc() == 1) {				// No arguments; Display status
		client_print(id, print_console, "Plugin is currently %s.", get_pcvar_num(pEnabled) ? "enabled" : "disabled");
		return PLUGIN_HANDLED;
	}

	new arg[2];
	read_argv(1, arg, 1);

	new num = str_to_num(arg);

	if ((num < 0) || (num > 1) || (!isdigit(arg[0]))) {	// If less than 0 or greater than 1 or not a digit
		if (id) {
			client_print(id, print_console, "Invalid argument(%s). Valid arguments are ^"0^" and ^"1^".", arg);
		} else {
			server_print("Invalid argument(%s). Valid arguments are ^"0^" and ^"1^".", arg);
		}
		return PLUGIN_HANDLED;
	}

	if (num == get_pcvar_num(pEnabled)) {
		if (id) {
			client_print(id, print_console, "Plugin is already %s.", num ? "enabled" : "disabled");
		} else {
			server_print("Plugin is already %s.", num ? "enabled" : "disabled");
		}
		return PLUGIN_HANDLED;
	}

	set_pcvar_num(pEnabled, num);

	if (id) {
		client_print(id, print_console, "Plugin was %s.", num ? "enabled" : "disabled");
	} else {
		server_print("Plugin was %s.", num ? "enabled" : "disabled");
	}

	if (num && get_pcvar_num(pOverride)) {
		set_molotovs();
	} else {
		reset_molotovs();
	}
	return PLUGIN_HANDLED;
}

public cmd_MolotovGive(id, level, cid) {

#if defined MOLOTOV_DEBUG
	log_amx("[MC] cmd_MolotovGive");
#endif
	if (!cmd_access(id, level, cid, 2)) {
		return PLUGIN_HANDLED;
	}

	new Arg1[64], target;
	read_argv(1, Arg1, 63);

	new adminName[32];
	get_user_name(id, adminName, 31);

	new targetTeam, targetTeamName[32];
	new Players[32], iNum;
#if defined MOLOTOV_DEBUG
	log_amx("[MC] cmd_MolotovGive Arg1[0](%s) Arg1[1](%s)", Arg1[0], Arg1[1]);
#endif
	if (Arg1[0] == '@') {

		if (equali(Arg1[1], "all")) {
			targetTeam = 0;
		} else if (equali(Arg1[1], "t") || equali(Arg1[1], "al")) {	// CS_TEAM_T or ALLIES
			targetTeam = TEAM_ONE;
		} else if (equali(Arg1[1], "ct") || equali(Arg1[1], "ax")) {	// CS_TEAM_CT or AXIS
			targetTeam = TEAM_TWO;
		}

		get_players(Players, iNum, "ac");	// Bots don't understand molotov cocktails

		for (new i = 0; i < iNum; ++i) {
			target = Players[i];

			if ((targetTeam == 0) || (get_user_team(target) == targetTeam)) {
				g_hasMolotov[target] = MOLOTOV_HARD_LIMIT;

				give_item(target, "weapon_smokegrenade");
				cs_set_user_bpammo(target, CSW_SMOKEGRENADE, MOLOTOV_HARD_LIMIT);
				emit_sound(target, CHAN_WEAPON, "items/gunpickup2.wav", VOL_NORM, ATTN_NORM, 0, PITCH_NORM);
			}
		}

		switch(targetTeam) {
			case 0: {
				targetTeamName = "everyone";
			}
			case 1: {
				if (cstrike_running()) {
					targetTeamName = "all terrorists";
				} else if (is_running("dod")) {
					targetTeamName = "all allies";
				} else {
					targetTeamName = "team 1";
				}
			}
			case 2: {
				if (cstrike_running()) {
					targetTeamName = "all ct's";
				} else if (is_running("dod")) {
					targetTeamName = "all axis";
				} else {
					targetTeamName = "team 2";
				}
			}
		}
		client_print(0, print_chat, "ADMIN %s: has given %s %d Molotov Cocktails!", adminName, targetTeamName, MOLOTOV_HARD_LIMIT);

	} else {

		target = cmd_target(id, Arg1, 0);

		if (!is_user_connected(target) || !is_user_alive(target)) {
			return PLUGIN_HANDLED;
		}

		new targetName[32];
		get_user_name(target, targetName, 31);

		g_hasMolotov[target] = MOLOTOV_HARD_LIMIT;

		give_item(target, "weapon_smokegrenade");
		cs_set_user_bpammo(target, CSW_SMOKEGRENADE, MOLOTOV_HARD_LIMIT);

		emit_sound(target, CHAN_WEAPON, "items/gunpickup2.wav", VOL_NORM, ATTN_NORM, 0, PITCH_NORM);

		client_print(target, print_chat, "ADMIN %s: has given you %d Molotov Cocktails!", adminName, MOLOTOV_HARD_LIMIT);

	}
	return PLUGIN_HANDLED;
}

public buy_molotov(id) {

	if (!get_pcvar_num(pEnabled)) {
		return PLUGIN_HANDLED;
	}

	if (get_pcvar_num(pOverride)) {
		if (get_pcvar_num(pBuyMenu)) {
			client_print(id, print_center, "Buy them in the buy equipment menu.");
		} else {
			client_print(id, print_center, "Just buy a HE grenade and get molotov automatically!");
		}
		return PLUGIN_HANDLED;
	}

	if (!is_user_alive(id)) {
		client_print(id, print_center, "Sen Molotov Kokteyli Alamassin Cunku Olusun");
		return PLUGIN_HANDLED;
	}

	if (!cs_get_user_buyzone(id) && get_pcvar_num(pBuyZone)==1&&!is_vip(id)) {
		client_print(id, print_center, "Burada Molotov Kokteyli Alamassin.");
		return PLUGIN_HANDLED;
	}

	new money = cs_get_user_money(id);

	if (money < get_pcvar_num(pPrice)) {
		client_print(id, print_center, "Molotov Kokteyli Almak Icin Yeterli Paran Yok");
		return PLUGIN_HANDLED;
	}

	if (g_hasMolotov[id] == get_pcvar_num(pMaxMolotovs)&&!is_vip(id)) {
		if (g_hasMolotov[id] == 1) {
			client_print(id, print_center, "Sen Molotov Kokteyline Sahipsin");
		} else {
			client_print(id, print_center, "Sende %d Molotov Cocktail Var.", g_hasMolotov[id]);
		}
		return PLUGIN_HANDLED;
	}
	if(g_hasMolotiv[id]==MAXIM_GRENADE_VIP&&is_vip(id))
	{
		client_print(id, print_center, "Ai atins maximum de molotov pentru VIP-uri!");
		return PLUGIN_HANDLED
	}

	if (!g_hasMolotov[id] && user_has_weapon(id, CSW_SMOKEGRENADE)) {
		client_print(id, print_center, "You already have a HE Grenade.");
		return PLUGIN_HANDLED;
	}

	cs_set_user_money(id, money - get_pcvar_num(pPrice));
	give_item(id, "weapon_smokegrenade");
	cs_set_user_bpammo(id, CSW_SMOKEGRENADE, ++g_hasMolotov[id]);
	client_print(id, print_chat, "Sen Molotov Kokteyli Aldin");

	return PLUGIN_HANDLED;
}

public event_BuyMenuCT(id) {

	if (!get_pcvar_num(pEnabled) || !get_pcvar_num(pBuyMenu)) {
		return PLUGIN_CONTINUE;
	}

	new Override = get_pcvar_num(pOverride);

	new menu[1024];
	new len = formatex(menu, 1023, "\yBuy Equipment\R$ Cost");

	len += formatex(menu[len], 1023-len, "^n^n\w1. Kevlar Vest\R\y650");
	len += formatex(menu[len], 1023-len, "^n\w2. Kevlar Vest & Helmet\R\y1000");
	len += formatex(menu[len], 1023-len, "^n\w3. Flashbang\R\y200");

	if (Override) {
		len += formatex(menu[len], 1023-len, "^n\w4. Molotov Cocktail\R\y%d", get_pcvar_num(pPrice));
	} else {
		len += formatex(menu[len], 1023-len, "^n\w4. HE Grenade\R\y300");
	}

	len += formatex(menu[len], 1023-len, "^n\w5. Smoke Grenade\R\y300");
	len += formatex(menu[len], 1023-len, "^n\w6. NightVision Goggles\R\y1250");
	len += formatex(menu[len], 1023-len, "^n\%c7. Defuse Kit\R\y200 ", g_bomb_map ? 'w' : 'd');
	len += formatex(menu[len], 1023-len, "^n\w8. Tactical Shield\R\y2200");

	if (!Override) {
		len += formatex(menu[len], 1023-len, "^n\w9. Molotov Cocktail\R\y%d", get_pcvar_num(pPrice));
	}

	len += formatex(menu[len], 1023-len, "^n^n\w0. Exit");

	show_menu(id, read_data(1)|MENU_KEY_9, menu, -1, "#CT_BuyItem");

	return PLUGIN_HANDLED;
}

public event_BuyMenuT(id) {

	if (!get_pcvar_num(pEnabled) || !get_pcvar_num(pBuyMenu)) {
		return PLUGIN_CONTINUE;
	}

	new Override = get_pcvar_num(pOverride);

	new menu[1024];
	new len = formatex(menu, 1023, "\yBuy Equipment\R$ Cost");
	len += formatex(menu[len], 1023-len, "^n^n\w1. Kevlar Vest\R\y650");
	len += formatex(menu[len], 1023-len, "^n\w2. Kevlar Vest & Helmet\R\y1000");
	len += formatex(menu[len], 1023-len, "^n\w3. Flashbang\R\y200");

	if (Override) {
		len += formatex(menu[len], 1023-len, "^n\w4. Molotov Cocktail\R\y%d", get_pcvar_num(pPrice));
	} else {
		len += formatex(menu[len], 1023-len, "^n\w4. HE Grenade\R\y300");
	}

	len += formatex(menu[len], 1023-len, "^n\w5. Smoke Grenade\R\y300");
	len += formatex(menu[len], 1023-len, "^n\w6. NightVision Goggles\R\y1250");

	if (!Override) {
		len += formatex(menu[len], 1023-len, "^n\w7. Molotov Cocktail\R\y%d", get_pcvar_num(pPrice));
	}

	len += formatex(menu[len], 1023-len, "^n^n\w0. Exit");

	show_menu(id, read_data(1)|MENU_KEY_7, menu, -1, "#T_BuyItem");

	return PLUGIN_HANDLED;
}

public handle_BuyMenuCT(id, key) {

	if (key == (get_pcvar_num(pOverride) ? 3 : 8)) {
		handle_BuyMenu(id);
		return PLUGIN_HANDLED;
	}

	return PLUGIN_CONTINUE;
}

public handle_BuyMenuT(id, key) {

	if (key == (get_pcvar_num(pOverride) ? 3 : 6)) {
		handle_BuyMenu(id);
		return PLUGIN_HANDLED;
	}

	return PLUGIN_CONTINUE;
}

stock handle_BuyMenu(id) {

	new money = cs_get_user_money(id);

	if (money < get_pcvar_num(pPrice)) {
		client_print(id, print_center, "Molotov Kokteyli Alman Icin Yeterli Paran Yok");
		return PLUGIN_HANDLED;
	}

	if (g_hasMolotov[id] == get_pcvar_num(pMaxMolotovs)) {
		if (g_hasMolotov[id] == 1) {
			client_print(id, print_center, "Sen Molotov Kokteyline Sahipsin");
		} else {
			client_print(id, print_center, "Sende %d Molotov Cocktail Var.", g_hasMolotov[id]);
		}
		return PLUGIN_HANDLED;
	} else if (!g_hasMolotov[id] && user_has_weapon(id, CSW_SMOKEGRENADE)) {
		client_print(id, print_center, "You already have a SM Grenade.");
		return PLUGIN_HANDLED;
	}

	cs_set_user_money(id, money - get_pcvar_num(pPrice));
	give_item(id, "weapon_smokegrenade");
	cs_set_user_bpammo(id, CSW_SMOKEGRENADE, ++g_hasMolotov[id]);
	client_print(id, print_chat, "You got a Molotov Cocktail!");

	return PLUGIN_HANDLED;
}

public grenade_throw(id, ent, wid) {

	if (!get_pcvar_num(pEnabled) || !is_user_connected(id) || wid != CSW_SMOKEGRENADE) {
		return PLUGIN_CONTINUE;
	}

	if (!g_hasMolotov[id] && !get_pcvar_num(pOverride)) {
		return PLUGIN_CONTINUE;
	}

	g_hasMolotov[id]--;
	engfunc(EngFunc_SetModel, ent, "models/molotov/w_molotov.mdl");
	set_pev(ent, pev_nextthink, 99999.0);

	return PLUGIN_CONTINUE;
}

public grenade_explode(ent) {

	new param[6], iOrigin[3];
	new Float:fOrigin[3];
	new owner = pev(ent, pev_owner);
	new ent2 = engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, "info_target"));

	pev(ent, pev_origin, fOrigin);

#if defined MOLOTOV_DEBUG
	new iOwnerAlive = is_user_alive(owner);
	new iOwnerConnected = is_user_connected(owner);
	new iEnt2Valid = pev_valid(ent2);
	log_amx("[MC] grenade_explode ent(%d) owner(%d) ent2(%d) iOwnerAlive(%d) iOwnerConnected(%d) iEnt2Valid(%d)", ent, owner, ent2, iOwnerAlive, iOwnerConnected, iEnt2Valid);
#endif

	param[0] = ent;
	param[1] = ent2;
	param[2] = owner;
	param[3] = iOrigin[0] = floatround(fOrigin[0]);
	param[4] = iOrigin[1] = floatround(fOrigin[1]);
	param[5] = iOrigin[2] = floatround(fOrigin[2]);

	emit_sound(ent, CHAN_AUTO, "molotov/molotov_fire.wav", VOL_NORM, ATTN_NORM, 0, PITCH_NORM);

	engfunc(EngFunc_SetModel, ent, "models/molotov/w_broke_molotov.mdl");

	random_fire(iOrigin, ent2);
	radius_damage(owner, fOrigin, get_pcvar_float(pMlDamage), get_pcvar_float(pMlRadius), DMG_BLAST);

	new Float:FireTime = get_pcvar_float(pFireTime);

	if (++g_Molotov_offset[owner] == MOLOTOV_HARD_LIMIT) {
		g_Molotov_offset[owner] = 0;
	}

	set_task(0.2, "fire_damage", MOLOTOV_TASKID_BASE1 + (MOLOTOV_TASKID_OFFSET * (owner - 1)) + g_Molotov_offset[owner], param, 6, "a", floatround(FireTime / 0.2, floatround_floor));
	set_task(1.0, "fire_sound", MOLOTOV_TASKID_BASE2 + (MOLOTOV_TASKID_OFFSET * (owner - 1)) + g_Molotov_offset[owner], param, 6, "a", floatround(FireTime) - 1);
	set_task(FireTime, "fire_stop", MOLOTOV_TASKID_BASE3 + (MOLOTOV_TASKID_OFFSET * (owner - 1)) + g_Molotov_offset[owner], param, 6);

	return PLUGIN_CONTINUE;
}

public fire_sound(param[]) {
	emit_sound(param[1], CHAN_AUTO, "molotov/molotov_fire.wav", VOL_NORM, ATTN_NORM, 0, PITCH_NORM);
}

public fire_stop(param[]) {
	g_g = 0;

	if (pev_valid(param[0])) { engfunc(EngFunc_RemoveEntity, param[0]); }
	if (pev_valid(param[1])) { engfunc(EngFunc_RemoveEntity, param[1]); }

	if ((last_Molotov_ent = (param[0]))) {
		last_Molotov_ent = 0;
	}
}

public fire_damage(param[]) {

	new iOrigin[3], Float:fOrigin[3];
	iOrigin[0] = param[3];
	iOrigin[1] = param[4];
	iOrigin[2] = param[5];

	random_fire(iOrigin, param[1]);

	IVecFVec(iOrigin, fOrigin);
	radius_damage(param[2], fOrigin, get_pcvar_float(pFireDmg), get_pcvar_float(pMlRadius), DMG_BURN, 0);
}

stock radius_damage(attacker, Float:origin[3], Float:damage, Float:range, dmgtype, calc = 1) {

	new Float:pOrigin[3], Float:dist, Float:tmpdmg;
	new i, ateam = get_user_team(attacker), iFF = get_pcvar_num(pFriendlyFire);

	while (i++ < g_MaxPlayers) {
		if (!is_user_alive(i)) {
			continue;
		}

		if (!iFF && ateam == get_user_team(i)) {
			continue;
		}

		pev(i, pev_origin, pOrigin);
		dist = get_distance_f(origin, pOrigin);

		if (dist > range) {
			continue;
		}

		if (calc) {
			tmpdmg = damage - (damage / range) * dist;
		} else {
			tmpdmg = damage;
		}

		if (pev(i, pev_health) < tmpdmg) {
			kill(attacker, i);
		} else {
			fm_fakedamage(i, "molotov", tmpdmg, dmgtype);
		}
	}

	while ((i = engfunc(EngFunc_FindEntityInSphere, i, origin, range))) {	// warning 211: possibly unintended assignment
		if (pev(i, pev_takedamage)) {
			if (calc) {
				pev(i, pev_origin, pOrigin);
				tmpdmg = damage - (damage / range) * get_distance_f(origin, pOrigin);
			} else {
				tmpdmg = damage;
			}
			fm_fakedamage(i, "molotov", tmpdmg, dmgtype);
		}
	}
}

stock random_fire(Origin[3], ent) {

	new range = get_pcvar_num(pMlRadius);
	new iOrigin[3];

	for (new i = 1; i <= 5; i++) {

		g_g = 1;

		iOrigin[0] = Origin[0] + random_num(-range, range);
		iOrigin[1] = Origin[1] + random_num(-range, range);
		iOrigin[2] = Origin[2];
		iOrigin[2] = ground_z(iOrigin, ent);

		while (get_distance(iOrigin, Origin) > range) {
			g_g++;
#if defined MOLOTOV_DEBUG
			//log_amx("[MC] random_fire ent(%d) i(%d) g_g(%d)", ent, i, g_g);
#endif
			iOrigin[0] = Origin[0] + random_num(-range, range);
			iOrigin[1] = Origin[1] + random_num(-range, range);
			iOrigin[2] = Origin[2];

			if (g_g >= ANTI_LAGG) {
				iOrigin[2] = ground_z(iOrigin, ent, 1);
			} else {
				iOrigin[2] = ground_z(iOrigin, ent);
			}
		}

		new rand = random_num(5, 15);

		message_begin(MSG_BROADCAST, SVC_TEMPENTITY);
		write_byte(TE_SPRITE);
		write_coord(iOrigin[0]);
		write_coord(iOrigin[1]);
		write_coord(iOrigin[2] + rand * 5);
		write_short(firespr);
		write_byte(rand);
		write_byte(100);
		message_end();

		if (!(i % 4)) {	// Smoke every 4th flame
			message_begin(MSG_BROADCAST, SVC_TEMPENTITY);
			write_byte(TE_SMOKE);
			write_coord(iOrigin[0]);
			write_coord(iOrigin[1]);
			write_coord(iOrigin[2] + 120);
			write_short(smokespr[random_num(0, 1)]);
			write_byte(random_num(10, 30));
			write_byte(random_num(10, 20));
			message_end();
		}
	}
}

stock kill(k, v) {

	user_silentkill(v);

	new kteam = get_user_team(k);
	new vteam = get_user_team(v);

	new kfrags = get_user_frags(k) + 1;
	new kdeaths = get_user_deaths(k);
	if (kteam == vteam) {
		kfrags = get_user_frags(k) - 2;
	}

	new vfrags = get_user_frags(v);
	new vdeaths = get_user_deaths(v);

	message_begin(MSG_ALL, gmsgScoreInfo);
	write_byte(k);
	write_short(kfrags);
	write_short(kdeaths);
	write_short(0);
	write_short(kteam);
	message_end();

	message_begin(MSG_ALL, gmsgScoreInfo);
	write_byte(v);
	write_short(vfrags + 1);
	write_short(vdeaths);
	write_short(0);
	write_short(vteam);
	message_end();

	message_begin(MSG_ALL, gmsgDeathMsg, {0,0,0}, 0);
	write_byte(k);
	write_byte(v);
	write_byte(0);
	write_string("molotov");
	message_end();

	g_frags[k]++;

	if (kteam != vteam) {
		cs_set_user_money(k, cs_get_user_money(k) + 300);
	} else {
		cs_set_user_money(k, cs_get_user_money(k) - 300);
	}
}

stock ground_z(iOrigin[3], ent, skip = 0, iRecursion = 0) {

#if defined MOLOTOV_DEBUG
	new iEntValid = pev_valid(ent);
	if (iRecursion > 0) {
		log_amx("[MC] ground_z ent(%d) iEntValid(%d) skip(%d) iRecursion(%d)", ent, iEntValid, skip, iRecursion);
	}
#endif
	iOrigin[2] += random_num(5, 80);

	if (!pev_valid(ent)) {	// Fix for: Run time error 10: native error (native "set_pev")
		return iOrigin[2];
	}

	new Float:fOrigin[3];

	IVecFVec(iOrigin, fOrigin);

	set_pev(ent, pev_origin, fOrigin);

	engfunc(EngFunc_DropToFloor, ent);

	if (!skip && !engfunc(EngFunc_EntIsOnFloor, ent)) {
		if (iRecursion >= ANTI_LAGG) {
			skip = 1;
		}
#if defined MOLOTOV_DEBUG
		log_amx("[MC] ground_z ++iRecursion(%d)", ++iRecursion);
		return ground_z(iOrigin, ent, skip, iRecursion);
#else
		return ground_z(iOrigin, ent, skip, ++iRecursion);
#endif
	}

	pev(ent, pev_origin, fOrigin);

	return floatround(fOrigin[2]);
}

stock reset_molotovs() {
	new ent = g_MaxPlayers;
	while ((ent = engfunc(EngFunc_FindEntityByString, ent, "model", "models/molotov/w_molotov.mdl"))) {
		engfunc(EngFunc_SetModel, ent, "models/w_smokegrenade.mdl");
	}
}

stock set_molotovs() {
	new ent = g_MaxPlayers;
	while ((ent = engfunc(EngFunc_FindEntityByString, ent, "model", "models/w_smokegrenade.mdl"))) {
		engfunc(EngFunc_SetModel, ent, "models/molotov/w_molotov.mdl");
	}
}

// This will run at event New Round if enabled
public show_molotov_menu(id) {
	new menu[192];

	// Get a custom menu title with the price
	// When done it should look something like this:
	// Buy Molotov Cocktail ($1200)...
	new menu_title_text[120], the_molotov_price[7];
	get_cvar_string("molotov_price", the_molotov_price, 6);
	strcat(menu_title_text, "Buy Molotov Cocktail ($", 40);
	strcat(menu_title_text, the_molotov_price, 40);
	strcat(menu_title_text, ")?^n^n1. Yes, I will burn them all...^n2. No, I will kill in some other way...^n^n0. EXIT MENU", 119);

	format(menu, 191, menu_title_text);

	// This shows the menu for 30 seconds, I tried first with get_cvar_num("mp_buytime")*60 , but it didn't work well
	// when using 0.5 as mp_buytime. If you like, just change the time below
	show_menu(id, MOLOTOV_MENU_KEYS, menu, 30);

	return PLUGIN_HANDLED;
}

//Our menu function will get the player id and the key they pressed
public giveMolotov(id, key) {

	//key will start at zero
	if (key == 0) {
		buy_molotov(id);
	} else if (key == 1) {
		client_print(id, print_center, ">You have chosen not to buy a Molotov Coctail<");
	} else {
		client_print(id, print_center, ">You have choosen to exit the molotov menu...<");
	}
}
Pentru ajutor, faceți cerere bine detaliată, completând și respectând modelul corespunzător.
Nu-mi mai dați cereri doar pentru a mă avea în lista de prieteni.
Dacă te ajut, și mă ignori/etc > te adaug în „foe”.
Aveți grijă la cei ce încearcă să mă copieze sau să dea drept mine..Puteți lua legătura cu mine prin STEAM dacă aveți o problemă/nelămurire în acest caz! Cont de forum am doar aici.
În cazul în care utilizați ceva din ce am postat(ex: aici), e bine să fiți la curent cu modificările aduse și de aici, iar dacă sunt ceva probleme nu ezitați să luați legătura cu mine. Actualizarea unor coduri nu se vor afișa public, doar dacă se găsește ceva critic/urgent de remediat, unele fiind coduri vechi iar unele refăcute chiar recent dar private.
* Nume pe cs1.6: eVoLuTiOn \ Nume vechi: eVo
* Atelierul meu - post2819572.html#p2819572 (închis, click link ca să vedeți de ce)
diavolu111
Membru, skill +1
Membru, skill +1
Posts: 419
Joined: 11 Oct 2014, 18:18
Detinator Steam: Da
Fond eXtream: 0
Location: Alba Iulia
Has thanked: 28 times
Been thanked: 6 times
Contact:

12 Mar 2020, 00:32

acum e la fel ca prima data cand l-ai editat :)) nu merge, iar vip pot sa cumpere de cate ori vor molotov... ca sa nu te mai chinui, daca sti tu alt plugin de genul poti sa-l lasi aici ca nu am nevoie neaparat de versiunea asta :)
User avatar
levin
Scripter eXtreamCS
Scripter eXtreamCS
Posts: 3844
Joined: 24 Aug 2011, 12:24
Detinator Steam: Da
CS Status:
Detinator server CS: ☯∴
SteamID: riseofevo
Reputatie: Scripter eXtreamCS
Nume anterior: Adryyy
Location: ҳ̸Ҳ̸ҳ
Discord: devilclass
Has thanked: 36 times
Been thanked: 594 times
Contact:

12 Mar 2020, 19:35

nu e vina mea că hosturile din românia oferă versiuni din 2010, la mine merge perfect
sau că nu puteți repune/copia sursa corectă

Code: Select all

/*******************************************************************************
			Molotov Cocktail
			  Version 3.20
		Maintained by: DynamicBits (Andy)

* Commands:
- say molotov - Buy a molotov
- say /molotov - Buy a molotov
- molotov_give <player|@all|@t|@ct|@al|@ax> - Gives molotovs to a player, a team, or everyone
- molotov_cocktail [0|1] - Enable/disable the plugin (If no arguments, show the status)
- molotov_override [0|1] - Enable/disable the HE grenade override (If no arguments, show the status)

* Cvars
- molotov_enabled - Enable/disable the plugin [1 = enabled; 0 = disabled] [default = 1]
- molotov_price - Set the molotov price [default = 1200]
- molotov_damage - Set the damage done by initial molotov explosion [default = 50.0]
- molotov_radius - Set the radius of molotov damage [default = 150.0]
- molotov_firetime - Duration (in seconds) of fire effects, sounds, etc. [default = 6]
- molotov_firedamage - Amount of damage done by fire effects (every 0.2 secs). [default = 3]
- molotov_ff - Disable(0)/enable(1) the ability to damage/kill someone on your team with molotov. [default = 1] (Was molotov_tk)
- molotov_override_he - Override the original hegrenade automaticly with molotov. [default = 0] (Was molotov_tempoverride)
- molotov_max - Max num of molotovs able to carry. [default = 1] (Does not work with override)
- molotov_inmenu - Puts molotov in the end of the equipment buymenu (old menu, not VGUI). [default = 0]
		   (If the override cvar is enabled the hegrenade will be replaced instead.)
- molotov_buyzone - Do you have to be in buyzone? [default = 1] (If molotov_inmenu=1, this is ignored)
- molotov_menu - Enables menu at beginning of each round [default = 0] (Was amx_molotovmenu)

* Required Modules:
- Fakemeta
- Fun
- Cstrike
- CSX

* Changelog/Credit:
- DynamicBits
  * Version 3.20 (2008-11-20)
    - My first public release
    - Finally tracked down and fixed the intermittent crashing problem (I hope!)
    - Modified default damage values
    - molotov_cocktail/molotov_override commands now change settings *or* display status
    - Broken molotov model stays closer to the explosion (looks more realistic)
    - Task IDs are now guaranteed to be unique
    - Modified anti-lag calculations to be more accurate (less likely to lag)
    - Changed amx_molotovmenu CVAR to molotov_menu
    - Changed molotov_tk CVAR to molotov_ff
    - Changed molotov_tempoverride CVAR to molotov_override_he
    - Preparation for support of mods other than Counter-Strike
    - Fixed lots of coding mistakes
    - Optimized several sections of code
    - Corrected grammar/typos
    - Clean up code (Removed unused code/unhelpful comments, fixed formatting, and semicolons!)
- Raffe (CantShoot)
  * (Unversioned release)
    - Originally fixed plugin to run on Linux servers
    - Added optional menu to purchase molotov cocktails each round
    - Moved models and sounds into proper molotov/ subdirectories
    - Fixed molotovs not being reset upon player disconnect
    - (Almost) fixed molotovs not being removed for new round
    - Added @all/@ct/@t arguments to cmd_MolotovGive
    - Changed some models/sound
- [ --<-@ ] Black Rose
  * Version 3.0-3.1c ?
    - Unknown changes
- SAMURAI
  * Original plugin author


*/

#include <amxmodx>
#include <amxmisc>
#include <fakemeta>
#include <cstrike>
#include <csx>
#include <fun>
#include <hamsandwich>
#include <fakemeta_util>

#define vip_flag "t"
#define is_vip(%1)	(get_user_flags(%1)&read_flags(vip_flag))
#define MAXIM_GRENADE_VIP 3

// pev_ field used to store custom nade types and their values
const PEV_NADE_TYPE = pev_flTimeStepSound
const NADE_TYPE_MOLOTOV = 681857

// Uncomment the following line to enable debug logging.
//#define MOLOTOV_DEBUG

#define AUTHORS "DynamicBits"

#define ADMIN_ACCESS ADMIN_KICK

#define ANTI_LAGG 7.0	// Defines max calculations before a flame is spawned without check if onground
// This is to prevent lagg at really narrow ents where you could end up with 400 calculations per flame
// Suggested: <= 10

#define MOLOTOV_HARD_LIMIT 10	// Maximum molotov cocktails this code is capable of handling without bugs
				// Also how many cocktails people get with molotov_give command

#define MOLOTOV_MENU_KEYS MENU_KEY_0|MENU_KEY_1|MENU_KEY_2	// Choices to look for with optional menu

#define MOLOTOV_TASKID_BASE 1000				// What is the lowest task ID?
#define MOLOTOV_TASKID_OFFSET MOLOTOV_HARD_LIMIT
#define MOLOTOV_TASKID_BASE1 MOLOTOV_TASKID_BASE				 // By default, with 32 players, task ids
#define MOLOTOV_TASKID_BASE2 MOLOTOV_TASKID_BASE1 + (MOLOTOV_TASKID_OFFSET * 32) // from 1000 to 1959 can
#define MOLOTOV_TASKID_BASE3 MOLOTOV_TASKID_BASE2 + (MOLOTOV_TASKID_OFFSET * 32) // potentially be used used.

#define TEAM_UNASSIGNED 0
#define TEAM_ONE	1
#define TEAM_TWO	2
#define TEAM_SPECTATOR	3

new pEnabled, pPrice, pMlDamage, pMlRadius, pFireTime, pOverride;
new pFriendlyFire, pFireDmg, pMaxMolotovs, pBuyMenu, pBuyZone, pMolotovMenu;

new gmsgScoreInfo, gmsgDeathMsg;

new g_pAllocModel, g_vAllocModel;

new g_frags[33];
new g_hasMolotov[33];
new g_restarted;
new g_MaxPlayers;
new g_bomb_map;

new firespr, smokespr[2];

new last_Molotov_ent;
new g_Molotov_offset[33];

new g_g;

public plugin_init() {

	register_plugin("Molotov Cocktail", "3.20", AUTHORS);

	register_menucmd(register_menuid("Buy Molotov Coctail"), MOLOTOV_MENU_KEYS, "giveMolotov");
#if defined MOLOTOV_DEBUG
	register_clcmd("molotov_menutest", "show_molotov_menu");
#endif

	register_clcmd("say /molotov", "buy_molotov");

	register_concmd("molotov_give", "cmd_MolotovGive", ADMIN_ACCESS, "<player|@all|@t|@ct|@al|@ax> - Gives free molotov cocktails (default=10)");
	register_concmd("molotov_override", "cmd_Override", ADMIN_ACCESS, "[0|1] - Enable/disable the HE grenade override (If no arguments, show the status)");
	register_concmd("molotov_cocktail", "cmd_PluginStatus", ADMIN_ACCESS, "[0|1] - Enable/disable the plugin (If no arguments, show the status)");

	pEnabled = register_cvar("molotov_enabled", "1", FCVAR_SPONLY);
	pOverride = register_cvar("molotov_override_he", "0", FCVAR_SPONLY);
	pPrice = register_cvar("molotov_price", "4000", FCVAR_SPONLY);
	pMlDamage = register_cvar("molotov_damage", "50.0", FCVAR_SPONLY);
	pMlRadius = register_cvar("molotov_radius", "150.0", FCVAR_SPONLY);
	pFireTime = register_cvar("molotov_firetime", "7", FCVAR_SPONLY);
	pFireDmg = register_cvar("molotov_firedamage", "4", FCVAR_SPONLY);
	pFriendlyFire = register_cvar("molotov_ff", "0", FCVAR_SPONLY);
	pMaxMolotovs = register_cvar("molotov_max", "10", FCVAR_SPONLY);
	pBuyMenu = register_cvar("molotov_inmenu", "0", FCVAR_SPONLY);
	pBuyZone = register_cvar("molotov_buyzone", "1", FCVAR_SPONLY);
	pMolotovMenu = register_cvar("molotov_menu", "0", FCVAR_SPONLY);

	register_event("CurWeapon", "Event_CurWeapon", "be", "1=1");
	register_event("HLTV", "event_new_round", "a", "1=0", "2=0");
	register_event("TextMsg", "Event_GameRestart", "a", "2=#Game_Commencing", "2=#Game_will_restart_in");
	register_event("DeathMsg", "event_DeathMsg", "a");

	register_event("ShowMenu", "event_BuyMenuT", "b", "4=#T_BuyItem", "1=575");
	register_event("ShowMenu", "event_BuyMenuCT", "b", "4=#CT_BuyItem", "1=703");
	register_event("ShowMenu", "event_BuyMenuT", "b", "4=#DT_BuyItem", "1=575");
	register_event("ShowMenu", "event_BuyMenuCT", "b", "4=#DCT_BuyItem", "1=767");

	register_logevent("logevent_Round_End", 2, "1=Round_End");

	register_menucmd(register_menuid("#CT_BuyItem"), 1023, "handle_BuyMenuCT");
	register_menucmd(register_menuid("#T_BuyItem"), 1023, "handle_BuyMenuT");

	RegisterHam(Ham_Think, "grenade", "fw_GrenadeThink")
	register_forward(FM_SetModel, "fw_SetModel")

	g_MaxPlayers = get_maxplayers();

	gmsgScoreInfo = get_user_msgid("ScoreInfo");
	gmsgDeathMsg = get_user_msgid("DeathMsg");

	g_pAllocModel = engfunc(EngFunc_AllocString, "models/molotov/p_molotov.mdl");
	g_vAllocModel = engfunc(EngFunc_AllocString, "models/molotov/v_molotov.mdl");

	g_bomb_map = engfunc(EngFunc_FindEntityByString, g_MaxPlayers, "classname", "info_bomb_target") ? 1 : 0;
}

public plugin_precache() {
	firespr = precache_model("sprites/flame.spr");

	smokespr[0] = precache_model("sprites/black_smoke3.spr");
	smokespr[1] = precache_model("sprites/steam1.spr");

	precache_sound("molotov/molotov_fire.wav");

	precache_model("models/molotov/p_molotov.mdl");
	precache_model("models/molotov/v_molotov.mdl");
	precache_model("models/molotov/w_molotov.mdl");
	precache_model("models/molotov/w_broke_molotov.mdl");
}

public client_disconnect(id)	g_hasMolotov[id] = 0;

public fw_SetModel(Ent, const Model[])
{
	static id; id = pev(Ent, pev_owner)
	if(!is_user_connected(id)) return FMRES_IGNORED
		
	static Float:DMGTime; pev(Ent, pev_dmgtime, DMGTime)
	if(DMGTime == 0.0) return FMRES_IGNORED
	
	if(equal(Model, "models/lotov/w_molotov.mdl") && g_hasMolotov[id])
	{
		set_pev(Ent, PEV_NADE_TYPE, NADE_TYPE_MOLOTOV)
		return FMRES_SUPERCEDE
	}
	return FMRES_IGNORED
}
public fw_GrenadeThink(Ent) {
	if(!pev_valid(Ent) || pev(Ent, PEV_NADE_TYPE) != NADE_TYPE_MOLOTOV) 	return HAM_IGNORED
	
	static Float:DMGTime; pev(Ent, pev_dmgtime, DMGTime)
	if(DMGTime > get_gametime()) 	return HAM_IGNORED

	new Float:fFriction, Float:fVelocity[3];
	pev(Ent, pev_friction, fFriction);
	pev(Ent, pev_velocity, fVelocity);

	fFriction *= 1.3;	// Increase friction to make it look more realistic
	set_pev(Ent, pev_friction, fFriction);
#if defined MOLOTOV_DEBUG
	log_amx("[MC] ent:%d Friction:%f Velocity:%f/%f/%f ====================", Ent, fFriction, fVelocity[0], fVelocity[1], fVelocity[2]);
#endif
	grenade_explode(Ent);

	return HAM_SUPERCEDE
}

public Event_CurWeapon(id) {
	if (!get_pcvar_num(pEnabled) || !is_user_alive(id))	return PLUGIN_CONTINUE;
	if (!g_hasMolotov[id] && !get_pcvar_num(pOverride))	return PLUGIN_CONTINUE;

	new WeaponID = get_user_weapon(id, WeaponID, WeaponID);
	if (WeaponID != CSW_SMOKEGRENADE)	return PLUGIN_CONTINUE;

	set_pev(id, pev_viewmodel, g_vAllocModel);
	set_pev(id, pev_weaponmodel, g_pAllocModel);
	set_pev(id, pev_weaponanim, 9);

	return PLUGIN_CONTINUE;
}

public Event_GameRestart()	g_restarted = 1;

public event_DeathMsg()	g_hasMolotov[read_data(2)] = 0;

public logevent_Round_End() {
#if defined MOLOTOV_DEBUG
	log_amx("[MC] ========== Round_End ==========");
#endif
	reset_tasks();
}

stock reset_tasks() {
#if defined MOLOTOV_DEBUG
	new tmpdbgid;
#endif
	for (new i; i < g_MaxPlayers; i++) {
		for (new o; o < MOLOTOV_TASKID_OFFSET; o++) {	//TODO DEBUG: Verify this fixes the tasks not reset at new round issue
			if (task_exists(MOLOTOV_TASKID_BASE1 + (MOLOTOV_TASKID_OFFSET * i) + o)) {
				remove_task(MOLOTOV_TASKID_BASE1 + (MOLOTOV_TASKID_OFFSET * i) + o);
#if defined MOLOTOV_DEBUG
				tmpdbgid = MOLOTOV_TASKID_BASE1 + (MOLOTOV_TASKID_OFFSET * i) + o;
				log_amx("[MC] %d exists. ----------==========----------", tmpdbgid);
#endif
			}

			if (task_exists(MOLOTOV_TASKID_BASE2 + (MOLOTOV_TASKID_OFFSET * i) + o)) {
				remove_task(MOLOTOV_TASKID_BASE2 + (MOLOTOV_TASKID_OFFSET * i) + o);
#if defined MOLOTOV_DEBUG
				tmpdbgid = MOLOTOV_TASKID_BASE2 + (MOLOTOV_TASKID_OFFSET * i) + o;
				log_amx("[MC] %d exists. ----------==========----------", tmpdbgid);
#endif
			}

			if (task_exists(MOLOTOV_TASKID_BASE3 + (MOLOTOV_TASKID_OFFSET * i) + o)) {
				remove_task(MOLOTOV_TASKID_BASE3 + (MOLOTOV_TASKID_OFFSET * i) + o);
#if defined MOLOTOV_DEBUG
				tmpdbgid = MOLOTOV_TASKID_BASE3 + (MOLOTOV_TASKID_OFFSET * i) + o;
				log_amx("[MC] %d exists. ----------==========----------", tmpdbgid);
#endif
			}
		}
	}
}

public event_new_round(id) {
#if defined MOLOTOV_DEBUG
	log_amx("[MC] ========== event_new_round ==========");
#endif
	if (!get_pcvar_num(pEnabled)) {
		return PLUGIN_CONTINUE;
	}

	reset_tasks();	// DEBUG

	if (get_pcvar_num(pMolotovMenu)) {
		show_molotov_menu(id);
	}

	for (new i; i < g_MaxPlayers; i++) {
		if (g_frags[i] && is_user_connected(i)) {
			set_user_frags(i, get_user_frags(i) + g_frags[i]);
		}
		g_frags[i] = 0;
	}

	if (g_restarted) {
		for (new i; i < g_MaxPlayers; i++) {
			g_hasMolotov[i] = 0;
		}
		g_restarted = 0;
	}

	if (get_pcvar_num(pOverride)) {
		set_molotovs();
	} else {
		reset_molotovs();
	}

	return PLUGIN_CONTINUE;
}

public cmd_Override(id, level, cid) {	
	if (!cmd_access(id, level, cid, 1)) {		// First argument (passed to molotov_override) is optional
		return PLUGIN_HANDLED;
	}

	if (!get_pcvar_num(pEnabled)) return PLUGIN_HANDLED;

	if (read_argc() == 1) {				// No arguments; Display status
		client_print(id, print_console, "Override is currently %s.", get_pcvar_num(pOverride) ? "enabled" : "disabled");
		return PLUGIN_HANDLED;
	}

	new arg[2];
	read_argv(1, arg, 1);

	new num = str_to_num(arg);

	if ((num < 0) || (num > 1) || (!isdigit(arg[0]))) {	// If less than 0 or greater than 1 or not a digit
		if (id) {
			client_print(id, print_console, "Invalid argument(%s). Valid arguments are ^"0^" and ^"1^".", arg);
		} else {
			server_print("Invalid argument(%s). Valid arguments are ^"0^" and ^"1^".", arg);
		}
		return PLUGIN_HANDLED;
	}

	if (num == get_pcvar_num(pOverride)) {
		if (id) {
			client_print(id, print_console, "Override is already %s.", num ? "enabled" : "disabled");
		} else {
			server_print("Override is already %s.", num ? "enabled" : "disabled");
		}
		return PLUGIN_HANDLED;
	}

	set_pcvar_num(pOverride, num);

	if (id) {
		client_print(id, print_console, "Override was %s.", num ? "enabled" : "disabled");
	} else {
		server_print("Override was %s.", num ? "enabled" : "disabled");
	}

	if (num) {
		set_molotovs();
	} else {
		reset_molotovs();
	}

	return PLUGIN_HANDLED;
}

public cmd_PluginStatus(id, level, cid) {
	if (!cmd_access(id, level, cid, 1)) {		// First argument (passed to molotov_cocktail) is optional
		return PLUGIN_HANDLED;
	}

	if (read_argc() == 1) {				// No arguments; Display status
		client_print(id, print_console, "Plugin is currently %s.", get_pcvar_num(pEnabled) ? "enabled" : "disabled");
		return PLUGIN_HANDLED;
	}

	new arg[2];
	read_argv(1, arg, 1);

	new num = str_to_num(arg);

	if ((num < 0) || (num > 1) || (!isdigit(arg[0]))) {	// If less than 0 or greater than 1 or not a digit
		if (id) {
			client_print(id, print_console, "Invalid argument(%s). Valid arguments are ^"0^" and ^"1^".", arg);
		} else {
			server_print("Invalid argument(%s). Valid arguments are ^"0^" and ^"1^".", arg);
		}
		return PLUGIN_HANDLED;
	}

	if (num == get_pcvar_num(pEnabled)) {
		if (id) {
			client_print(id, print_console, "Plugin is already %s.", num ? "enabled" : "disabled");
		} else {
			server_print("Plugin is already %s.", num ? "enabled" : "disabled");
		}
		return PLUGIN_HANDLED;
	}

	set_pcvar_num(pEnabled, num);

	if (id) {
		client_print(id, print_console, "Plugin was %s.", num ? "enabled" : "disabled");
	} else {
		server_print("Plugin was %s.", num ? "enabled" : "disabled");
	}

	if (num && get_pcvar_num(pOverride)) {
		set_molotovs();
	} else {
		reset_molotovs();
	}
	return PLUGIN_HANDLED;
}

public cmd_MolotovGive(id, level, cid) {

#if defined MOLOTOV_DEBUG
	log_amx("[MC] cmd_MolotovGive");
#endif
	if (!cmd_access(id, level, cid, 2)) {
		return PLUGIN_HANDLED;
	}

	new Arg1[64], target;
	read_argv(1, Arg1, 63);

	new adminName[32];
	get_user_name(id, adminName, 31);

	new targetTeam, targetTeamName[32];
	new Players[32], iNum;
#if defined MOLOTOV_DEBUG
	log_amx("[MC] cmd_MolotovGive Arg1[0](%s) Arg1[1](%s)", Arg1[0], Arg1[1]);
#endif
	if (Arg1[0] == '@') {

		if (equali(Arg1[1], "all")) {
			targetTeam = 0;
		} else if (equali(Arg1[1], "t") || equali(Arg1[1], "al")) {	// CS_TEAM_T or ALLIES
			targetTeam = TEAM_ONE;
		} else if (equali(Arg1[1], "ct") || equali(Arg1[1], "ax")) {	// CS_TEAM_CT or AXIS
			targetTeam = TEAM_TWO;
		}

		get_players(Players, iNum, "ac");	// Bots don't understand molotov cocktails

		for (new i = 0; i < iNum; ++i) {
			target = Players[i];

			if ((targetTeam == 0) || (get_user_team(target) == targetTeam)) {
				g_hasMolotov[target] = MOLOTOV_HARD_LIMIT;

				give_item(target, "weapon_smokegrenade");
				cs_set_user_bpammo(target, CSW_SMOKEGRENADE, MOLOTOV_HARD_LIMIT);
				emit_sound(target, CHAN_WEAPON, "items/gunpickup2.wav", VOL_NORM, ATTN_NORM, 0, PITCH_NORM);
			}
		}

		switch(targetTeam) {
			case 0: {
				targetTeamName = "everyone";
			}
			case 1: {
				if (cstrike_running()) {
					targetTeamName = "all terrorists";
				} else if (is_running("dod")) {
					targetTeamName = "all allies";
				} else {
					targetTeamName = "team 1";
				}
			}
			case 2: {
				if (cstrike_running()) {
					targetTeamName = "all ct's";
				} else if (is_running("dod")) {
					targetTeamName = "all axis";
				} else {
					targetTeamName = "team 2";
				}
			}
		}
		client_print(0, print_chat, "ADMIN %s: has given %s %d Molotov Cocktails!", adminName, targetTeamName, MOLOTOV_HARD_LIMIT);

	} else {

		target = cmd_target(id, Arg1, 0);

		if (!is_user_connected(target) || !is_user_alive(target)) {
			return PLUGIN_HANDLED;
		}

		new targetName[32];
		get_user_name(target, targetName, 31);

		g_hasMolotov[target] = MOLOTOV_HARD_LIMIT;

		give_item(target, "weapon_smokegrenade");
		cs_set_user_bpammo(target, CSW_SMOKEGRENADE, MOLOTOV_HARD_LIMIT);

		emit_sound(target, CHAN_WEAPON, "items/gunpickup2.wav", VOL_NORM, ATTN_NORM, 0, PITCH_NORM);

		client_print(target, print_chat, "ADMIN %s: has given you %d Molotov Cocktails!", adminName, MOLOTOV_HARD_LIMIT);

	}
	return PLUGIN_HANDLED;
}

public buy_molotov(id) {

	if (!get_pcvar_num(pEnabled)) {
		return PLUGIN_HANDLED;
	}

	if (get_pcvar_num(pOverride)) {
		if (get_pcvar_num(pBuyMenu)) {
			client_print(id, print_center, "Buy them in the buy equipment menu.");
		} else {
			client_print(id, print_center, "Just buy a HE grenade and get molotov automatically!");
		}
		return PLUGIN_HANDLED;
	}

	if (!is_user_alive(id)) {
		client_print(id, print_center, "Sen Molotov Kokteyli Alamassin Cunku Olusun");
		return PLUGIN_HANDLED;
	}

	if (!cs_get_user_buyzone(id) && get_pcvar_num(pBuyZone)==1&&!is_vip(id)) {
		client_print(id, print_center, "Burada Molotov Kokteyli Alamassin.");
		return PLUGIN_HANDLED;
	}

	new money = cs_get_user_money(id);

	if (money < get_pcvar_num(pPrice)) {
		client_print(id, print_center, "Molotov Kokteyli Almak Icin Yeterli Paran Yok");
		return PLUGIN_HANDLED;
	}

	if(is_vip(id))
	{
		if(g_hasMolotov[id]==MAXIM_GRENADE_VIP)
		{
			client_print(id, print_center, "Ai atins maximum de molotov pentru VIP-uri!");
			return PLUGIN_HANDLED
		}
	}
	else
	{
		if (g_hasMolotov[id] == get_pcvar_num(pMaxMolotovs)) {
			if (g_hasMolotov[id] == 1)	client_print(id, print_center, "Sen Molotov Kokteyline Sahipsin");
			else client_print(id, print_center, "Sende %d Molotov Cocktail Var.", g_hasMolotov[id]);
			return PLUGIN_HANDLED;
		}
	}

	if (!g_hasMolotov[id] && user_has_weapon(id, CSW_SMOKEGRENADE)) {
		client_print(id, print_center, "You already have a HE Grenade.");
		return PLUGIN_HANDLED;
	}

	cs_set_user_money(id, money - get_pcvar_num(pPrice));
	give_item(id, "weapon_smokegrenade");
	cs_set_user_bpammo(id, CSW_SMOKEGRENADE, ++g_hasMolotov[id]);
	client_print(id, print_chat, "Sen Molotov Kokteyli Aldin");

	return PLUGIN_HANDLED;
}

public event_BuyMenuCT(id) {

	if (!get_pcvar_num(pEnabled) || !get_pcvar_num(pBuyMenu)) {
		return PLUGIN_CONTINUE;
	}

	new Override = get_pcvar_num(pOverride);

	new menu[1024];
	new len = formatex(menu, 1023, "\yBuy Equipment\R$ Cost");

	len += formatex(menu[len], 1023-len, "^n^n\w1. Kevlar Vest\R\y650");
	len += formatex(menu[len], 1023-len, "^n\w2. Kevlar Vest & Helmet\R\y1000");
	len += formatex(menu[len], 1023-len, "^n\w3. Flashbang\R\y200");

	if (Override) {
		len += formatex(menu[len], 1023-len, "^n\w4. Molotov Cocktail\R\y%d", get_pcvar_num(pPrice));
	} else {
		len += formatex(menu[len], 1023-len, "^n\w4. HE Grenade\R\y300");
	}

	len += formatex(menu[len], 1023-len, "^n\w5. Smoke Grenade\R\y300");
	len += formatex(menu[len], 1023-len, "^n\w6. NightVision Goggles\R\y1250");
	len += formatex(menu[len], 1023-len, "^n\%c7. Defuse Kit\R\y200 ", g_bomb_map ? 'w' : 'd');
	len += formatex(menu[len], 1023-len, "^n\w8. Tactical Shield\R\y2200");

	if (!Override) {
		len += formatex(menu[len], 1023-len, "^n\w9. Molotov Cocktail\R\y%d", get_pcvar_num(pPrice));
	}

	len += formatex(menu[len], 1023-len, "^n^n\w0. Exit");

	show_menu(id, read_data(1)|MENU_KEY_9, menu, -1, "#CT_BuyItem");

	return PLUGIN_HANDLED;
}

public event_BuyMenuT(id) {

	if (!get_pcvar_num(pEnabled) || !get_pcvar_num(pBuyMenu)) {
		return PLUGIN_CONTINUE;
	}

	new Override = get_pcvar_num(pOverride);

	new menu[1024];
	new len = formatex(menu, 1023, "\yBuy Equipment\R$ Cost");
	len += formatex(menu[len], 1023-len, "^n^n\w1. Kevlar Vest\R\y650");
	len += formatex(menu[len], 1023-len, "^n\w2. Kevlar Vest & Helmet\R\y1000");
	len += formatex(menu[len], 1023-len, "^n\w3. Flashbang\R\y200");

	if (Override) {
		len += formatex(menu[len], 1023-len, "^n\w4. Molotov Cocktail\R\y%d", get_pcvar_num(pPrice));
	} else {
		len += formatex(menu[len], 1023-len, "^n\w4. HE Grenade\R\y300");
	}

	len += formatex(menu[len], 1023-len, "^n\w5. Smoke Grenade\R\y300");
	len += formatex(menu[len], 1023-len, "^n\w6. NightVision Goggles\R\y1250");

	if (!Override) {
		len += formatex(menu[len], 1023-len, "^n\w7. Molotov Cocktail\R\y%d", get_pcvar_num(pPrice));
	}

	len += formatex(menu[len], 1023-len, "^n^n\w0. Exit");

	show_menu(id, read_data(1)|MENU_KEY_7, menu, -1, "#T_BuyItem");

	return PLUGIN_HANDLED;
}

public handle_BuyMenuCT(id, key) {

	if (key == (get_pcvar_num(pOverride) ? 3 : 8)) {
		handle_BuyMenu(id);
		return PLUGIN_HANDLED;
	}

	return PLUGIN_CONTINUE;
}

public handle_BuyMenuT(id, key) {
	if (key == (get_pcvar_num(pOverride) ? 3 : 6)) {
		handle_BuyMenu(id);
		return PLUGIN_HANDLED;
	}

	return PLUGIN_CONTINUE;
}

stock handle_BuyMenu(id) {
	new money = cs_get_user_money(id);

	if (money < get_pcvar_num(pPrice)) {
		client_print(id, print_center, "Molotov Kokteyli Alman Icin Yeterli Paran Yok");
		return PLUGIN_HANDLED;
	}

	if (g_hasMolotov[id] == get_pcvar_num(pMaxMolotovs)) {
		if (g_hasMolotov[id] == 1) {
			client_print(id, print_center, "Sen Molotov Kokteyline Sahipsin");
		} else {
			client_print(id, print_center, "Sende %d Molotov Cocktail Var.", g_hasMolotov[id]);
		}
		return PLUGIN_HANDLED;
	} else if (!g_hasMolotov[id] && user_has_weapon(id, CSW_SMOKEGRENADE)) {
		client_print(id, print_center, "You already have a SM Grenade.");
		return PLUGIN_HANDLED;
	}

	cs_set_user_money(id, money - get_pcvar_num(pPrice));
	give_item(id, "weapon_smokegrenade");
	cs_set_user_bpammo(id, CSW_SMOKEGRENADE, ++g_hasMolotov[id]);
	client_print(id, print_chat, "You got a Molotov Cocktail!");

	return PLUGIN_HANDLED;
}

public grenade_throw(id, ent, wid) {
	if (!get_pcvar_num(pEnabled) || !is_user_connected(id) || wid != CSW_SMOKEGRENADE) return PLUGIN_CONTINUE;

	if (!g_hasMolotov[id] && !get_pcvar_num(pOverride)) return PLUGIN_CONTINUE;

	g_hasMolotov[id]--;
	engfunc(EngFunc_SetModel, ent, "models/molotov/w_molotov.mdl");
	set_pev(ent, pev_nextthink, 99999.0);

	return PLUGIN_CONTINUE;
}

public grenade_explode(ent) {
	new param[6], iOrigin[3];
	new Float:fOrigin[3];
	new owner = pev(ent, pev_owner);
	new ent2 = engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, "info_target"));

	pev(ent, pev_origin, fOrigin);

#if defined MOLOTOV_DEBUG
	new iOwnerAlive = is_user_alive(owner);
	new iOwnerConnected = is_user_connected(owner);
	new iEnt2Valid = pev_valid(ent2);
	log_amx("[MC] grenade_explode ent(%d) owner(%d) ent2(%d) iOwnerAlive(%d) iOwnerConnected(%d) iEnt2Valid(%d)", ent, owner, ent2, iOwnerAlive, iOwnerConnected, iEnt2Valid);
#endif

	param[0] = ent;
	param[1] = ent2;
	param[2] = owner;
	param[3] = iOrigin[0] = floatround(fOrigin[0]);
	param[4] = iOrigin[1] = floatround(fOrigin[1]);
	param[5] = iOrigin[2] = floatround(fOrigin[2]);

	emit_sound(ent, CHAN_AUTO, "molotov/molotov_fire.wav", VOL_NORM, ATTN_NORM, 0, PITCH_NORM);

	engfunc(EngFunc_SetModel, ent, "models/molotov/w_broke_molotov.mdl");

	random_fire(iOrigin, ent2);
	radius_damage(owner, fOrigin, get_pcvar_float(pMlDamage), get_pcvar_float(pMlRadius), DMG_BLAST);

	new Float:FireTime = get_pcvar_float(pFireTime);

	if (++g_Molotov_offset[owner] == MOLOTOV_HARD_LIMIT) g_Molotov_offset[owner] = 0;

	set_task(0.2, "fire_damage", MOLOTOV_TASKID_BASE1 + (MOLOTOV_TASKID_OFFSET * (owner - 1)) + g_Molotov_offset[owner], param, 6, "a", floatround(FireTime / 0.2, floatround_floor));
	set_task(1.0, "fire_sound", MOLOTOV_TASKID_BASE2 + (MOLOTOV_TASKID_OFFSET * (owner - 1)) + g_Molotov_offset[owner], param, 6, "a", floatround(FireTime) - 1);
	set_task(FireTime, "fire_stop", MOLOTOV_TASKID_BASE3 + (MOLOTOV_TASKID_OFFSET * (owner - 1)) + g_Molotov_offset[owner], param, 6);

	return PLUGIN_CONTINUE;
}

public fire_sound(param[]) emit_sound(param[1], CHAN_AUTO, "molotov/molotov_fire.wav", VOL_NORM, ATTN_NORM, 0, PITCH_NORM);

public fire_stop(param[]) {
	g_g = 0;

	if (pev_valid(param[0])) { engfunc(EngFunc_RemoveEntity, param[0]); }
	if (pev_valid(param[1])) { engfunc(EngFunc_RemoveEntity, param[1]); }

	if ((last_Molotov_ent = (param[0])))	last_Molotov_ent = 0;
}

public fire_damage(param[]) {
	new iOrigin[3], Float:fOrigin[3];
	iOrigin[0] = param[3];
	iOrigin[1] = param[4];
	iOrigin[2] = param[5];

	random_fire(iOrigin, param[1]);

	IVecFVec(iOrigin, fOrigin);
	radius_damage(param[2], fOrigin, get_pcvar_float(pFireDmg), get_pcvar_float(pMlRadius), DMG_BURN, 0);
}

stock radius_damage(attacker, Float:origin[3], Float:damage, Float:range, dmgtype, calc = 1) {
	new Float:pOrigin[3], Float:dist, Float:tmpdmg;
	new i, ateam = get_user_team(attacker), iFF = get_pcvar_num(pFriendlyFire);

	while (i++ < g_MaxPlayers) {
		if (!is_user_alive(i)) continue;

		if (!iFF && ateam == get_user_team(i)) continue;

		pev(i, pev_origin, pOrigin);
		dist = get_distance_f(origin, pOrigin);

		if (dist > range) continue;

		if (calc) tmpdmg = damage - (damage / range) * dist;
		else tmpdmg = damage;

		if (pev(i, pev_health) < tmpdmg) kill(attacker, i);
		else fm_fakedamage(i, "molotov", tmpdmg, dmgtype);
	}

	while ((i = engfunc(EngFunc_FindEntityInSphere, i, origin, range))) {	// warning 211: possibly unintended assignment
		if (pev(i, pev_takedamage)) {
			if (calc) {
				pev(i, pev_origin, pOrigin);
				tmpdmg = damage - (damage / range) * get_distance_f(origin, pOrigin);
			} else tmpdmg = damage;
			fm_fakedamage(i, "molotov", tmpdmg, dmgtype);
		}
	}
}

stock random_fire(Origin[3], ent) {
	new range = get_pcvar_num(pMlRadius);
	new iOrigin[3];

	for (new i = 1; i <= 5; i++) {
		g_g = 1;

		iOrigin[0] = Origin[0] + random_num(-range, range);
		iOrigin[1] = Origin[1] + random_num(-range, range);
		iOrigin[2] = Origin[2];
		iOrigin[2] = ground_z(iOrigin, ent);

		while (get_distance(iOrigin, Origin) > range) {
			g_g++;
#if defined MOLOTOV_DEBUG
			//log_amx("[MC] random_fire ent(%d) i(%d) g_g(%d)", ent, i, g_g);
#endif
			iOrigin[0] = Origin[0] + random_num(-range, range);
			iOrigin[1] = Origin[1] + random_num(-range, range);
			iOrigin[2] = Origin[2];

			if (g_g >= ANTI_LAGG) iOrigin[2] = ground_z(iOrigin, ent, 1);
			else iOrigin[2] = ground_z(iOrigin, ent);
		}

		new rand = random_num(5, 15);

		message_begin(MSG_BROADCAST, SVC_TEMPENTITY);
		write_byte(TE_SPRITE);
		write_coord(iOrigin[0]);
		write_coord(iOrigin[1]);
		write_coord(iOrigin[2] + rand * 5);
		write_short(firespr);
		write_byte(rand);
		write_byte(100);
		message_end();

		if (!(i % 4)) {	// Smoke every 4th flame
			message_begin(MSG_BROADCAST, SVC_TEMPENTITY);
			write_byte(TE_SMOKE);
			write_coord(iOrigin[0]);
			write_coord(iOrigin[1]);
			write_coord(iOrigin[2] + 120);
			write_short(smokespr[random_num(0, 1)]);
			write_byte(random_num(10, 30));
			write_byte(random_num(10, 20));
			message_end();
		}
	}
}

stock kill(k, v) {
	user_silentkill(v);

	new kteam = get_user_team(k);
	new vteam = get_user_team(v);

	new kfrags = get_user_frags(k) + 1;
	new kdeaths = get_user_deaths(k);
	if (kteam == vteam) kfrags = get_user_frags(k) - 2;

	new vfrags = get_user_frags(v);
	new vdeaths = get_user_deaths(v);

	message_begin(MSG_ALL, gmsgScoreInfo);
	write_byte(k);
	write_short(kfrags);
	write_short(kdeaths);
	write_short(0);
	write_short(kteam);
	message_end();

	message_begin(MSG_ALL, gmsgScoreInfo);
	write_byte(v);
	write_short(vfrags + 1);
	write_short(vdeaths);
	write_short(0);
	write_short(vteam);
	message_end();

	message_begin(MSG_ALL, gmsgDeathMsg, {0,0,0}, 0);
	write_byte(k);
	write_byte(v);
	write_byte(0);
	write_string("molotov");
	message_end();

	g_frags[k]++;

	if (kteam != vteam) cs_set_user_money(k, cs_get_user_money(k) + 300);
	else cs_set_user_money(k, cs_get_user_money(k) - 300);
}

stock ground_z(iOrigin[3], ent, skip = 0, iRecursion = 0) {

#if defined MOLOTOV_DEBUG
	new iEntValid = pev_valid(ent);
	if (iRecursion > 0) log_amx("[MC] ground_z ent(%d) iEntValid(%d) skip(%d) iRecursion(%d)", ent, iEntValid, skip, iRecursion);
#endif
	iOrigin[2] += random_num(5, 80);

	if (!pev_valid(ent)) {	// Fix for: Run time error 10: native error (native "set_pev")
		return iOrigin[2];
	}

	new Float:fOrigin[3];

	IVecFVec(iOrigin, fOrigin);

	set_pev(ent, pev_origin, fOrigin);

	engfunc(EngFunc_DropToFloor, ent);

	if (!skip && !engfunc(EngFunc_EntIsOnFloor, ent)) {
		if (iRecursion >= ANTI_LAGG) skip = 1;
#if defined MOLOTOV_DEBUG
		log_amx("[MC] ground_z ++iRecursion(%d)", ++iRecursion);
		return ground_z(iOrigin, ent, skip, iRecursion);
#else
		return ground_z(iOrigin, ent, skip, ++iRecursion);
#endif
	}

	pev(ent, pev_origin, fOrigin);

	return floatround(fOrigin[2]);
}

stock reset_molotovs() {
	new ent = g_MaxPlayers;
	while ((ent = engfunc(EngFunc_FindEntityByString, ent, "model", "models/molotov/w_molotov.mdl"))) {
		engfunc(EngFunc_SetModel, ent, "models/w_smokegrenade.mdl");
	}
}

stock set_molotovs() {
	new ent = g_MaxPlayers;
	while ((ent = engfunc(EngFunc_FindEntityByString, ent, "model", "models/w_smokegrenade.mdl"))) {
		engfunc(EngFunc_SetModel, ent, "models/molotov/w_molotov.mdl");
	}
}

// This will run at event New Round if enabled
public show_molotov_menu(id) {
	new menu[192];

	// Get a custom menu title with the price
	// When done it should look something like this:
	// Buy Molotov Cocktail ($1200)...
	new menu_title_text[120], the_molotov_price[7];
	get_cvar_string("molotov_price", the_molotov_price, 6);
	strcat(menu_title_text, "Buy Molotov Cocktail ($", 40);
	strcat(menu_title_text, the_molotov_price, 40);
	strcat(menu_title_text, ")?^n^n1. Yes, I will burn them all...^n2. No, I will kill in some other way...^n^n0. EXIT MENU", 119);

	format(menu, 191, menu_title_text);

	// This shows the menu for 30 seconds, I tried first with get_cvar_num("mp_buytime")*60 , but it didn't work well
	// when using 0.5 as mp_buytime. If you like, just change the time below
	show_menu(id, MOLOTOV_MENU_KEYS, menu, 30);

	return PLUGIN_HANDLED;
}

//Our menu function will get the player id and the key they pressed
public giveMolotov(id, key) {
	//key will start at zero
	if (key == 0) buy_molotov(id);
	else if (key == 1) client_print(id, print_center, ">You have chosen not to buy a Molotov Coctail<");
	else client_print(id, print_center, ">You have choosen to exit the molotov menu...<");
}
Pentru ajutor, faceți cerere bine detaliată, completând și respectând modelul corespunzător.
Nu-mi mai dați cereri doar pentru a mă avea în lista de prieteni.
Dacă te ajut, și mă ignori/etc > te adaug în „foe”.
Aveți grijă la cei ce încearcă să mă copieze sau să dea drept mine..Puteți lua legătura cu mine prin STEAM dacă aveți o problemă/nelămurire în acest caz! Cont de forum am doar aici.
În cazul în care utilizați ceva din ce am postat(ex: aici), e bine să fiți la curent cu modificările aduse și de aici, iar dacă sunt ceva probleme nu ezitați să luați legătura cu mine. Actualizarea unor coduri nu se vor afișa public, doar dacă se găsește ceva critic/urgent de remediat, unele fiind coduri vechi iar unele refăcute chiar recent dar private.
* Nume pe cs1.6: eVoLuTiOn \ Nume vechi: eVo
* Atelierul meu - post2819572.html#p2819572 (închis, click link ca să vedeți de ce)
diavolu111
Membru, skill +1
Membru, skill +1
Posts: 419
Joined: 11 Oct 2014, 18:18
Detinator Steam: Da
Fond eXtream: 0
Location: Alba Iulia
Has thanked: 28 times
Been thanked: 6 times
Contact:

12 Mar 2020, 22:35

la fel... vip pot cumpara cate molotovuri vor si cand arunci grenada nu se intampla nimic... oricum eu nu am spus ca e vina ta... stiu multe pluginuri editate sau facute de tine care merg foarte bine, deci imi dau seama ca sti ce faci :)

daca te ajuta cu ceva:

Code: Select all

Currently running plugins:
 [  1] Reunion, v0.1.0.92, 2018-02-11, by The Legion, see 
 [  2] Rechecker, v2.5, Oct 21 2017, by s1lent, see http://www.dedicated-server.ru/
 [  3] ReAuthCheck, v0.1.6, 2017-03-08, by Adidasman, see http://www.dedicated-server.ru/
 [  4] AMX Mod X, v1.8.3-dev+5134, Aug  5 2017, by AMX Mod X Dev Team, see http://www.amxmodx.org
 [  5] MySQL, v1.8.3-dev+5134, Aug  5 2017, by AMX Mod X Dev Team, see http://www.amxmodx.org/
 [  6] SQLite, v1.8.3-dev+5134, Aug  5 2017, by AMX Mod X Dev Team, see http://www.amxmodx.org/
 [  7] Fun, v1.8.3-dev+5134, Aug  5 2017, by AMX Mod X Dev Team, see http://www.amxmodx.org
 [  8] Engine, v1.8.3-dev+5134, Aug  5 2017, by AMX Mod X Dev Team, see http://www.amxmodx.org
 [  9] FakeMeta, v1.8.3-dev+5134, Aug  5 2017, by AMX Mod X Dev Team, see http://www.amxmodx.org
 [ 10] GeoIP, v1.8.3-dev+5134, Aug  5 2017, by AMX Mod X Dev Team, see http://www.amxmodx.org/
 [ 11] CStrike, v1.8.3-dev+5135, Aug  5 2017, by AMX Mod X Dev Team, see http://www.amxmodx.org
 [ 12] CSX, v1.8.3-dev+5135, Aug  5 2017, by AMX Mod X Dev Team, see http://www.amxmodx.org/
 [ 13] Ham Sandwich, v1.8.3-dev+5134, Aug  5 2017, by AMX Mod X Dev Team, see http://www.amxmodx.org
 [ 14] ReAPI, v5.1.0.112-dev, 2017-06-13, by Asmodai & s1lent, see https://github.com/s1lentq/reapi/
User avatar
levin
Scripter eXtreamCS
Scripter eXtreamCS
Posts: 3844
Joined: 24 Aug 2011, 12:24
Detinator Steam: Da
CS Status:
Detinator server CS: ☯∴
SteamID: riseofevo
Reputatie: Scripter eXtreamCS
Nume anterior: Adryyy
Location: ҳ̸Ҳ̸ҳ
Discord: devilclass
Has thanked: 36 times
Been thanked: 594 times
Contact:

13 Mar 2020, 11:57

sunt erori în log?
a,era scrisă locația greșit
iar pentru vip n are cum să nu meargă, comanda e /molotov

Code: Select all

/*******************************************************************************
			Molotov Cocktail
			  Version 3.20
		Maintained by: DynamicBits (Andy)

* Commands:
- say molotov - Buy a molotov
- say /molotov - Buy a molotov
- molotov_give <player|@all|@t|@ct|@al|@ax> - Gives molotovs to a player, a team, or everyone
- molotov_cocktail [0|1] - Enable/disable the plugin (If no arguments, show the status)
- molotov_override [0|1] - Enable/disable the HE grenade override (If no arguments, show the status)

* Cvars
- molotov_enabled - Enable/disable the plugin [1 = enabled; 0 = disabled] [default = 1]
- molotov_price - Set the molotov price [default = 1200]
- molotov_damage - Set the damage done by initial molotov explosion [default = 50.0]
- molotov_radius - Set the radius of molotov damage [default = 150.0]
- molotov_firetime - Duration (in seconds) of fire effects, sounds, etc. [default = 6]
- molotov_firedamage - Amount of damage done by fire effects (every 0.2 secs). [default = 3]
- molotov_ff - Disable(0)/enable(1) the ability to damage/kill someone on your team with molotov. [default = 1] (Was molotov_tk)
- molotov_override_he - Override the original hegrenade automaticly with molotov. [default = 0] (Was molotov_tempoverride)
- molotov_max - Max num of molotovs able to carry. [default = 1] (Does not work with override)
- molotov_inmenu - Puts molotov in the end of the equipment buymenu (old menu, not VGUI). [default = 0]
		   (If the override cvar is enabled the hegrenade will be replaced instead.)
- molotov_buyzone - Do you have to be in buyzone? [default = 1] (If molotov_inmenu=1, this is ignored)
- molotov_menu - Enables menu at beginning of each round [default = 0] (Was amx_molotovmenu)

* Required Modules:
- Fakemeta
- Fun
- Cstrike
- CSX

* Changelog/Credit:
- DynamicBits
  * Version 3.20 (2008-11-20)
    - My first public release
    - Finally tracked down and fixed the intermittent crashing problem (I hope!)
    - Modified default damage values
    - molotov_cocktail/molotov_override commands now change settings *or* display status
    - Broken molotov model stays closer to the explosion (looks more realistic)
    - Task IDs are now guaranteed to be unique
    - Modified anti-lag calculations to be more accurate (less likely to lag)
    - Changed amx_molotovmenu CVAR to molotov_menu
    - Changed molotov_tk CVAR to molotov_ff
    - Changed molotov_tempoverride CVAR to molotov_override_he
    - Preparation for support of mods other than Counter-Strike
    - Fixed lots of coding mistakes
    - Optimized several sections of code
    - Corrected grammar/typos
    - Clean up code (Removed unused code/unhelpful comments, fixed formatting, and semicolons!)
- Raffe (CantShoot)
  * (Unversioned release)
    - Originally fixed plugin to run on Linux servers
    - Added optional menu to purchase molotov cocktails each round
    - Moved models and sounds into proper molotov/ subdirectories
    - Fixed molotovs not being reset upon player disconnect
    - (Almost) fixed molotovs not being removed for new round
    - Added @all/@ct/@t arguments to cmd_MolotovGive
    - Changed some models/sound
- [ --<-@ ] Black Rose
  * Version 3.0-3.1c ?
    - Unknown changes
- SAMURAI
  * Original plugin author


*/

#include <amxmodx>
#include <amxmisc>
#include <fakemeta>
#include <cstrike>
#include <csx>
#include <fun>
#include <hamsandwich>
#include <fakemeta_util>

#define vip_flag		"t"
#define is_vip(%1)		(get_user_flags(%1)&read_flags(vip_flag))
#define MAXIM_GRENADE_VIP	3

// pev_ field used to store custom nade types and their values
const PEV_NADE_TYPE = pev_flTimeStepSound
const NADE_TYPE_MOLOTOV = 681857

// Uncomment the following line to enable debug logging.
//#define MOLOTOV_DEBUG

#define AUTHORS "DynamicBits"

#define ADMIN_ACCESS ADMIN_KICK

#define ANTI_LAGG 7.0	// Defines max calculations before a flame is spawned without check if onground
// This is to prevent lagg at really narrow ents where you could end up with 400 calculations per flame
// Suggested: <= 10

#define MOLOTOV_HARD_LIMIT 10	// Maximum molotov cocktails this code is capable of handling without bugs
				// Also how many cocktails people get with molotov_give command

#define MOLOTOV_MENU_KEYS MENU_KEY_0|MENU_KEY_1|MENU_KEY_2	// Choices to look for with optional menu

#define MOLOTOV_TASKID_BASE 1000				// What is the lowest task ID?
#define MOLOTOV_TASKID_OFFSET MOLOTOV_HARD_LIMIT
#define MOLOTOV_TASKID_BASE1 MOLOTOV_TASKID_BASE				 // By default, with 32 players, task ids
#define MOLOTOV_TASKID_BASE2 MOLOTOV_TASKID_BASE1 + (MOLOTOV_TASKID_OFFSET * 32) // from 1000 to 1959 can
#define MOLOTOV_TASKID_BASE3 MOLOTOV_TASKID_BASE2 + (MOLOTOV_TASKID_OFFSET * 32) // potentially be used used.

#define TEAM_UNASSIGNED 0
#define TEAM_ONE	1
#define TEAM_TWO	2
#define TEAM_SPECTATOR	3

new pEnabled, pPrice, pMlDamage, pMlRadius, pFireTime, pOverride;
new pFriendlyFire, pFireDmg, pMaxMolotovs, pBuyMenu, pBuyZone, pMolotovMenu;

new gmsgScoreInfo, gmsgDeathMsg;

new g_pAllocModel, g_vAllocModel;

new g_frags[33];
new g_hasMolotov[33];
new g_restarted;
new g_MaxPlayers;
new g_bomb_map;

new firespr, smokespr[2];

new last_Molotov_ent;
new g_Molotov_offset[33];

new g_g;

public plugin_init() {

	register_plugin("Molotov Cocktail", "3.20", AUTHORS);

	register_menucmd(register_menuid("Buy Molotov Coctail"), MOLOTOV_MENU_KEYS, "giveMolotov");
#if defined MOLOTOV_DEBUG
	register_clcmd("molotov_menutest", "show_molotov_menu");
#endif

	register_clcmd("say /molotov", "buy_molotov");

	register_concmd("molotov_give", "cmd_MolotovGive", ADMIN_ACCESS, "<player|@all|@t|@ct|@al|@ax> - Gives free molotov cocktails (default=10)");
	register_concmd("molotov_override", "cmd_Override", ADMIN_ACCESS, "[0|1] - Enable/disable the HE grenade override (If no arguments, show the status)");
	register_concmd("molotov_cocktail", "cmd_PluginStatus", ADMIN_ACCESS, "[0|1] - Enable/disable the plugin (If no arguments, show the status)");

	pEnabled = register_cvar("molotov_enabled", "1", FCVAR_SPONLY);
	pOverride = register_cvar("molotov_override_he", "0", FCVAR_SPONLY);
	pPrice = register_cvar("molotov_price", "4000", FCVAR_SPONLY);
	pMlDamage = register_cvar("molotov_damage", "50.0", FCVAR_SPONLY);
	pMlRadius = register_cvar("molotov_radius", "150.0", FCVAR_SPONLY);
	pFireTime = register_cvar("molotov_firetime", "7", FCVAR_SPONLY);
	pFireDmg = register_cvar("molotov_firedamage", "4", FCVAR_SPONLY);
	pFriendlyFire = register_cvar("molotov_ff", "0", FCVAR_SPONLY);
	pMaxMolotovs = register_cvar("molotov_max", "10", FCVAR_SPONLY);
	pBuyMenu = register_cvar("molotov_inmenu", "0", FCVAR_SPONLY);
	pBuyZone = register_cvar("molotov_buyzone", "1", FCVAR_SPONLY);
	pMolotovMenu = register_cvar("molotov_menu", "0", FCVAR_SPONLY);

	register_event("CurWeapon", "Event_CurWeapon", "be", "1=1");
	register_event("HLTV", "event_new_round", "a", "1=0", "2=0");
	register_event("TextMsg", "Event_GameRestart", "a", "2=#Game_Commencing", "2=#Game_will_restart_in");
	register_event("DeathMsg", "event_DeathMsg", "a");

	register_event("ShowMenu", "event_BuyMenuT", "b", "4=#T_BuyItem", "1=575");
	register_event("ShowMenu", "event_BuyMenuCT", "b", "4=#CT_BuyItem", "1=703");
	register_event("ShowMenu", "event_BuyMenuT", "b", "4=#DT_BuyItem", "1=575");
	register_event("ShowMenu", "event_BuyMenuCT", "b", "4=#DCT_BuyItem", "1=767");

	register_logevent("logevent_Round_End", 2, "1=Round_End");

	register_menucmd(register_menuid("#CT_BuyItem"), 1023, "handle_BuyMenuCT");
	register_menucmd(register_menuid("#T_BuyItem"), 1023, "handle_BuyMenuT");

	RegisterHam(Ham_Think, "grenade", "fw_GrenadeThink")
	register_forward(FM_SetModel, "fw_SetModel")

	g_MaxPlayers = get_maxplayers();

	gmsgScoreInfo = get_user_msgid("ScoreInfo");
	gmsgDeathMsg = get_user_msgid("DeathMsg");

	g_pAllocModel = engfunc(EngFunc_AllocString, "models/molotov/p_molotov.mdl");
	g_vAllocModel = engfunc(EngFunc_AllocString, "models/molotov/v_molotov.mdl");

	g_bomb_map = engfunc(EngFunc_FindEntityByString, g_MaxPlayers, "classname", "info_bomb_target") ? 1 : 0;
}

public plugin_precache() {
	firespr = precache_model("sprites/flame.spr");

	smokespr[0] = precache_model("sprites/black_smoke3.spr");
	smokespr[1] = precache_model("sprites/steam1.spr");

	precache_sound("molotov/molotov_fire.wav");

	precache_model("models/molotov/p_molotov.mdl");
	precache_model("models/molotov/v_molotov.mdl");
	precache_model("models/molotov/w_molotov.mdl");
	precache_model("models/molotov/w_broke_molotov.mdl");
}

public client_disconnect(id)	g_hasMolotov[id] = 0;

public fw_SetModel(Ent, const Model[])
{
	static id; id = pev(Ent, pev_owner)
	if(!is_user_connected(id)) return FMRES_IGNORED
		
	static Float:DMGTime; pev(Ent, pev_dmgtime, DMGTime)
	if(DMGTime == 0.0) return FMRES_IGNORED
	
	if(equal(Model, "models/molotov/w_molotov.mdl") && g_hasMolotov[id])
	{
		set_pev(Ent, PEV_NADE_TYPE, NADE_TYPE_MOLOTOV)
		return FMRES_SUPERCEDE
	}
	return FMRES_IGNORED
}
public fw_GrenadeThink(Ent) {
	if(!pev_valid(Ent) || pev(Ent, PEV_NADE_TYPE) != NADE_TYPE_MOLOTOV) 	return HAM_IGNORED
	
	static Float:DMGTime; pev(Ent, pev_dmgtime, DMGTime)
	if(DMGTime > get_gametime()) 	return HAM_IGNORED

	new Float:fFriction, Float:fVelocity[3];
	pev(Ent, pev_friction, fFriction);
	pev(Ent, pev_velocity, fVelocity);

	fFriction *= 1.3;	// Increase friction to make it look more realistic
	set_pev(Ent, pev_friction, fFriction);
#if defined MOLOTOV_DEBUG
	log_amx("[MC] ent:%d Friction:%f Velocity:%f/%f/%f ====================", Ent, fFriction, fVelocity[0], fVelocity[1], fVelocity[2]);
#endif
	grenade_explode(Ent);

	return HAM_SUPERCEDE
}

public Event_CurWeapon(id) {
	if (!get_pcvar_num(pEnabled) || !is_user_alive(id))	return PLUGIN_CONTINUE;
	if (!g_hasMolotov[id] && !get_pcvar_num(pOverride))	return PLUGIN_CONTINUE;

	new WeaponID = get_user_weapon(id, WeaponID, WeaponID);
	if (WeaponID != CSW_SMOKEGRENADE)	return PLUGIN_CONTINUE;

	set_pev(id, pev_viewmodel, g_vAllocModel);
	set_pev(id, pev_weaponmodel, g_pAllocModel);
	set_pev(id, pev_weaponanim, 9);

	return PLUGIN_CONTINUE;
}

public Event_GameRestart()	g_restarted = 1;

public event_DeathMsg()	g_hasMolotov[read_data(2)] = 0;

public logevent_Round_End() {
#if defined MOLOTOV_DEBUG
	log_amx("[MC] ========== Round_End ==========");
#endif
	reset_tasks();
}

stock reset_tasks() {
#if defined MOLOTOV_DEBUG
	new tmpdbgid;
#endif
	for (new i; i < g_MaxPlayers; i++) {
		for (new o; o < MOLOTOV_TASKID_OFFSET; o++) {	//TODO DEBUG: Verify this fixes the tasks not reset at new round issue
			if (task_exists(MOLOTOV_TASKID_BASE1 + (MOLOTOV_TASKID_OFFSET * i) + o)) {
				remove_task(MOLOTOV_TASKID_BASE1 + (MOLOTOV_TASKID_OFFSET * i) + o);
#if defined MOLOTOV_DEBUG
				tmpdbgid = MOLOTOV_TASKID_BASE1 + (MOLOTOV_TASKID_OFFSET * i) + o;
				log_amx("[MC] %d exists. ----------==========----------", tmpdbgid);
#endif
			}

			if (task_exists(MOLOTOV_TASKID_BASE2 + (MOLOTOV_TASKID_OFFSET * i) + o)) {
				remove_task(MOLOTOV_TASKID_BASE2 + (MOLOTOV_TASKID_OFFSET * i) + o);
#if defined MOLOTOV_DEBUG
				tmpdbgid = MOLOTOV_TASKID_BASE2 + (MOLOTOV_TASKID_OFFSET * i) + o;
				log_amx("[MC] %d exists. ----------==========----------", tmpdbgid);
#endif
			}

			if (task_exists(MOLOTOV_TASKID_BASE3 + (MOLOTOV_TASKID_OFFSET * i) + o)) {
				remove_task(MOLOTOV_TASKID_BASE3 + (MOLOTOV_TASKID_OFFSET * i) + o);
#if defined MOLOTOV_DEBUG
				tmpdbgid = MOLOTOV_TASKID_BASE3 + (MOLOTOV_TASKID_OFFSET * i) + o;
				log_amx("[MC] %d exists. ----------==========----------", tmpdbgid);
#endif
			}
		}
	}
}

public event_new_round(id) {
#if defined MOLOTOV_DEBUG
	log_amx("[MC] ========== event_new_round ==========");
#endif
	if (!get_pcvar_num(pEnabled)) {
		return PLUGIN_CONTINUE;
	}

	reset_tasks();	// DEBUG

	if (get_pcvar_num(pMolotovMenu)) {
		show_molotov_menu(id);
	}

	for (new i; i < g_MaxPlayers; i++) {
		if (g_frags[i] && is_user_connected(i)) {
			set_user_frags(i, get_user_frags(i) + g_frags[i]);
		}
		g_frags[i] = 0;
	}

	if (g_restarted) {
		for (new i; i < g_MaxPlayers; i++) {
			g_hasMolotov[i] = 0;
		}
		g_restarted = 0;
	}

	if (get_pcvar_num(pOverride)) {
		set_molotovs();
	} else {
		reset_molotovs();
	}

	return PLUGIN_CONTINUE;
}

public cmd_Override(id, level, cid) {	
	if (!cmd_access(id, level, cid, 1)) {		// First argument (passed to molotov_override) is optional
		return PLUGIN_HANDLED;
	}

	if (!get_pcvar_num(pEnabled)) return PLUGIN_HANDLED;

	if (read_argc() == 1) {				// No arguments; Display status
		client_print(id, print_console, "Override is currently %s.", get_pcvar_num(pOverride) ? "enabled" : "disabled");
		return PLUGIN_HANDLED;
	}

	new arg[2];
	read_argv(1, arg, 1);

	new num = str_to_num(arg);

	if ((num < 0) || (num > 1) || (!isdigit(arg[0]))) {	// If less than 0 or greater than 1 or not a digit
		if (id) {
			client_print(id, print_console, "Invalid argument(%s). Valid arguments are ^"0^" and ^"1^".", arg);
		} else {
			server_print("Invalid argument(%s). Valid arguments are ^"0^" and ^"1^".", arg);
		}
		return PLUGIN_HANDLED;
	}

	if (num == get_pcvar_num(pOverride)) {
		if (id) {
			client_print(id, print_console, "Override is already %s.", num ? "enabled" : "disabled");
		} else {
			server_print("Override is already %s.", num ? "enabled" : "disabled");
		}
		return PLUGIN_HANDLED;
	}

	set_pcvar_num(pOverride, num);

	if (id) {
		client_print(id, print_console, "Override was %s.", num ? "enabled" : "disabled");
	} else {
		server_print("Override was %s.", num ? "enabled" : "disabled");
	}

	if (num) {
		set_molotovs();
	} else {
		reset_molotovs();
	}

	return PLUGIN_HANDLED;
}

public cmd_PluginStatus(id, level, cid) {
	if (!cmd_access(id, level, cid, 1)) {		// First argument (passed to molotov_cocktail) is optional
		return PLUGIN_HANDLED;
	}

	if (read_argc() == 1) {				// No arguments; Display status
		client_print(id, print_console, "Plugin is currently %s.", get_pcvar_num(pEnabled) ? "enabled" : "disabled");
		return PLUGIN_HANDLED;
	}

	new arg[2];
	read_argv(1, arg, 1);

	new num = str_to_num(arg);

	if ((num < 0) || (num > 1) || (!isdigit(arg[0]))) {	// If less than 0 or greater than 1 or not a digit
		if (id) {
			client_print(id, print_console, "Invalid argument(%s). Valid arguments are ^"0^" and ^"1^".", arg);
		} else {
			server_print("Invalid argument(%s). Valid arguments are ^"0^" and ^"1^".", arg);
		}
		return PLUGIN_HANDLED;
	}

	if (num == get_pcvar_num(pEnabled)) {
		if (id) {
			client_print(id, print_console, "Plugin is already %s.", num ? "enabled" : "disabled");
		} else {
			server_print("Plugin is already %s.", num ? "enabled" : "disabled");
		}
		return PLUGIN_HANDLED;
	}

	set_pcvar_num(pEnabled, num);

	if (id) {
		client_print(id, print_console, "Plugin was %s.", num ? "enabled" : "disabled");
	} else {
		server_print("Plugin was %s.", num ? "enabled" : "disabled");
	}

	if (num && get_pcvar_num(pOverride)) {
		set_molotovs();
	} else {
		reset_molotovs();
	}
	return PLUGIN_HANDLED;
}

public cmd_MolotovGive(id, level, cid) {

#if defined MOLOTOV_DEBUG
	log_amx("[MC] cmd_MolotovGive");
#endif
	if (!cmd_access(id, level, cid, 2)) {
		return PLUGIN_HANDLED;
	}

	new Arg1[64], target;
	read_argv(1, Arg1, 63);

	new adminName[32];
	get_user_name(id, adminName, 31);

	new targetTeam, targetTeamName[32];
	new Players[32], iNum;
#if defined MOLOTOV_DEBUG
	log_amx("[MC] cmd_MolotovGive Arg1[0](%s) Arg1[1](%s)", Arg1[0], Arg1[1]);
#endif
	if (Arg1[0] == '@') {

		if (equali(Arg1[1], "all")) {
			targetTeam = 0;
		} else if (equali(Arg1[1], "t") || equali(Arg1[1], "al")) {	// CS_TEAM_T or ALLIES
			targetTeam = TEAM_ONE;
		} else if (equali(Arg1[1], "ct") || equali(Arg1[1], "ax")) {	// CS_TEAM_CT or AXIS
			targetTeam = TEAM_TWO;
		}

		get_players(Players, iNum, "ac");	// Bots don't understand molotov cocktails

		for (new i = 0; i < iNum; ++i) {
			target = Players[i];

			if ((targetTeam == 0) || (get_user_team(target) == targetTeam)) {
				g_hasMolotov[target] = MOLOTOV_HARD_LIMIT;

				give_item(target, "weapon_smokegrenade");
				cs_set_user_bpammo(target, CSW_SMOKEGRENADE, MOLOTOV_HARD_LIMIT);
				emit_sound(target, CHAN_WEAPON, "items/gunpickup2.wav", VOL_NORM, ATTN_NORM, 0, PITCH_NORM);
			}
		}

		switch(targetTeam) {
			case 0: {
				targetTeamName = "everyone";
			}
			case 1: {
				if (cstrike_running()) {
					targetTeamName = "all terrorists";
				} else if (is_running("dod")) {
					targetTeamName = "all allies";
				} else {
					targetTeamName = "team 1";
				}
			}
			case 2: {
				if (cstrike_running()) {
					targetTeamName = "all ct's";
				} else if (is_running("dod")) {
					targetTeamName = "all axis";
				} else {
					targetTeamName = "team 2";
				}
			}
		}
		client_print(0, print_chat, "ADMIN %s: has given %s %d Molotov Cocktails!", adminName, targetTeamName, MOLOTOV_HARD_LIMIT);

	} else {
		target = cmd_target(id, Arg1, 0);

		if (!is_user_connected(target) || !is_user_alive(target)) {
			return PLUGIN_HANDLED;
		}

		new targetName[32];
		get_user_name(target, targetName, 31);

		g_hasMolotov[target] = MOLOTOV_HARD_LIMIT;

		give_item(target, "weapon_smokegrenade");
		cs_set_user_bpammo(target, CSW_SMOKEGRENADE, MOLOTOV_HARD_LIMIT);

		emit_sound(target, CHAN_WEAPON, "items/gunpickup2.wav", VOL_NORM, ATTN_NORM, 0, PITCH_NORM);

		client_print(target, print_chat, "ADMIN %s: has given you %d Molotov Cocktails!", adminName, MOLOTOV_HARD_LIMIT);

	}
	return PLUGIN_HANDLED;
}

public buy_molotov(id) {
	if (!get_pcvar_num(pEnabled)) return PLUGIN_HANDLED;

	if (get_pcvar_num(pOverride)) {
		if (get_pcvar_num(pBuyMenu)) client_print(id, print_center, "Buy them in the buy equipment menu.");
		else client_print(id, print_center, "Just buy a HE grenade and get molotov automatically!");
		return PLUGIN_HANDLED;
	}

	if (!is_user_alive(id)) {
		client_print(id, print_center, "Sen Molotov Kokteyli Alamassin Cunku Olusun");
		return PLUGIN_HANDLED;
	}

	if (!cs_get_user_buyzone(id) && get_pcvar_num(pBuyZone)==1&&!is_vip(id)) {
		client_print(id, print_center, "Burada Molotov Kokteyli Alamassin.");
		return PLUGIN_HANDLED;
	}

	new money = cs_get_user_money(id);
	if (money < get_pcvar_num(pPrice)) {
		client_print(id, print_center, "Molotov Kokteyli Almak Icin Yeterli Paran Yok");
		return PLUGIN_HANDLED;
	}

	if(is_vip(id))
	{
		if(g_hasMolotov[id]==MAXIM_GRENADE_VIP)
		{
			client_print(id, print_center, "Ai atins maximum de molotov pentru VIP-uri!");
			return PLUGIN_HANDLED
		}
	}
	else
	{
		if (g_hasMolotov[id] == get_pcvar_num(pMaxMolotovs)) {
			if (g_hasMolotov[id] == 1)	client_print(id, print_center, "Sen Molotov Kokteyline Sahipsin");
			else client_print(id, print_center, "Sende %d Molotov Cocktail Var.", g_hasMolotov[id]);
			return PLUGIN_HANDLED;
		}
	}

	if (!g_hasMolotov[id] && user_has_weapon(id, CSW_SMOKEGRENADE)) {
		client_print(id, print_center, "You already have a HE Grenade.");
		return PLUGIN_HANDLED;
	}

	cs_set_user_money(id, money - get_pcvar_num(pPrice));
	give_item(id, "weapon_smokegrenade");
	cs_set_user_bpammo(id, CSW_SMOKEGRENADE, ++g_hasMolotov[id]);
	client_print(id, print_chat, "Sen Molotov Kokteyli Aldin");

	return PLUGIN_HANDLED;
}

public event_BuyMenuCT(id) {
	if (!get_pcvar_num(pEnabled) || !get_pcvar_num(pBuyMenu)) return PLUGIN_CONTINUE;

	new Override = get_pcvar_num(pOverride);

	new menu[1024];
	new len = formatex(menu, 1023, "\yBuy Equipment\R$ Cost");

	len += formatex(menu[len], 1023-len, "^n^n\w1. Kevlar Vest\R\y650");
	len += formatex(menu[len], 1023-len, "^n\w2. Kevlar Vest & Helmet\R\y1000");
	len += formatex(menu[len], 1023-len, "^n\w3. Flashbang\R\y200");

	if (Override) len += formatex(menu[len], 1023-len, "^n\w4. Molotov Cocktail\R\y%d", get_pcvar_num(pPrice));
	else len += formatex(menu[len], 1023-len, "^n\w4. HE Grenade\R\y300");

	len += formatex(menu[len], 1023-len, "^n\w5. Smoke Grenade\R\y300");
	len += formatex(menu[len], 1023-len, "^n\w6. NightVision Goggles\R\y1250");
	len += formatex(menu[len], 1023-len, "^n\%c7. Defuse Kit\R\y200 ", g_bomb_map ? 'w' : 'd');
	len += formatex(menu[len], 1023-len, "^n\w8. Tactical Shield\R\y2200");

	if (!Override) len += formatex(menu[len], 1023-len, "^n\w9. Molotov Cocktail\R\y%d", get_pcvar_num(pPrice));

	len += formatex(menu[len], 1023-len, "^n^n\w0. Exit");

	show_menu(id, read_data(1)|MENU_KEY_9, menu, -1, "#CT_BuyItem");

	return PLUGIN_HANDLED;
}

public event_BuyMenuT(id) {
	if (!get_pcvar_num(pEnabled) || !get_pcvar_num(pBuyMenu)) return PLUGIN_CONTINUE;

	new Override = get_pcvar_num(pOverride);

	new menu[1024];
	new len = formatex(menu, 1023, "\yBuy Equipment\R$ Cost");
	len += formatex(menu[len], 1023-len, "^n^n\w1. Kevlar Vest\R\y650");
	len += formatex(menu[len], 1023-len, "^n\w2. Kevlar Vest & Helmet\R\y1000");
	len += formatex(menu[len], 1023-len, "^n\w3. Flashbang\R\y200");

	if (Override) len += formatex(menu[len], 1023-len, "^n\w4. Molotov Cocktail\R\y%d", get_pcvar_num(pPrice));
	else len += formatex(menu[len], 1023-len, "^n\w4. HE Grenade\R\y300");

	len += formatex(menu[len], 1023-len, "^n\w5. Smoke Grenade\R\y300");
	len += formatex(menu[len], 1023-len, "^n\w6. NightVision Goggles\R\y1250");

	if (!Override) len += formatex(menu[len], 1023-len, "^n\w7. Molotov Cocktail\R\y%d", get_pcvar_num(pPrice));

	len += formatex(menu[len], 1023-len, "^n^n\w0. Exit");

	show_menu(id, read_data(1)|MENU_KEY_7, menu, -1, "#T_BuyItem");

	return PLUGIN_HANDLED;
}

public handle_BuyMenuCT(id, key) {
	if (key == (get_pcvar_num(pOverride) ? 3 : 8)) {
		handle_BuyMenu(id);
		return PLUGIN_HANDLED;
	}

	return PLUGIN_CONTINUE;
}

public handle_BuyMenuT(id, key) {
	if (key == (get_pcvar_num(pOverride) ? 3 : 6)) {
		handle_BuyMenu(id);
		return PLUGIN_HANDLED;
	}

	return PLUGIN_CONTINUE;
}
stock handle_BuyMenu(id) {
	new money = cs_get_user_money(id);

	if (money < get_pcvar_num(pPrice)) {
		client_print(id, print_center, "Molotov Kokteyli Alman Icin Yeterli Paran Yok");
		return PLUGIN_HANDLED;
	}

	if (g_hasMolotov[id] == get_pcvar_num(pMaxMolotovs)) {
		if (g_hasMolotov[id] == 1) client_print(id, print_center, "Sen Molotov Kokteyline Sahipsin");
		else client_print(id, print_center, "Sende %d Molotov Cocktail Var.", g_hasMolotov[id]);
		return PLUGIN_HANDLED;
	} else if (!g_hasMolotov[id] && user_has_weapon(id, CSW_SMOKEGRENADE)) {
		client_print(id, print_center, "You already have a SM Grenade.");
		return PLUGIN_HANDLED;
	}

	cs_set_user_money(id, money - get_pcvar_num(pPrice));
	give_item(id, "weapon_smokegrenade");
	cs_set_user_bpammo(id, CSW_SMOKEGRENADE, ++g_hasMolotov[id]);
	client_print(id, print_chat, "You got a Molotov Cocktail!");

	return PLUGIN_HANDLED;
}

public grenade_throw(id, ent, wid) {
	if (!get_pcvar_num(pEnabled) || !is_user_connected(id) || wid != CSW_SMOKEGRENADE) return PLUGIN_CONTINUE;

	if (!g_hasMolotov[id] && !get_pcvar_num(pOverride)) return PLUGIN_CONTINUE;

	g_hasMolotov[id]--;
	engfunc(EngFunc_SetModel, ent, "models/molotov/w_molotov.mdl");
	set_pev(ent, pev_nextthink, 99999.0);

	return PLUGIN_CONTINUE;
}

public grenade_explode(ent) {
	new param[6], iOrigin[3];
	new Float:fOrigin[3];
	new owner = pev(ent, pev_owner);
	new ent2 = engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, "info_target"));

	pev(ent, pev_origin, fOrigin);

#if defined MOLOTOV_DEBUG
	new iOwnerAlive = is_user_alive(owner);
	new iOwnerConnected = is_user_connected(owner);
	new iEnt2Valid = pev_valid(ent2);
	log_amx("[MC] grenade_explode ent(%d) owner(%d) ent2(%d) iOwnerAlive(%d) iOwnerConnected(%d) iEnt2Valid(%d)", ent, owner, ent2, iOwnerAlive, iOwnerConnected, iEnt2Valid);
#endif

	param[0] = ent;
	param[1] = ent2;
	param[2] = owner;
	param[3] = iOrigin[0] = floatround(fOrigin[0]);
	param[4] = iOrigin[1] = floatround(fOrigin[1]);
	param[5] = iOrigin[2] = floatround(fOrigin[2]);

	emit_sound(ent, CHAN_AUTO, "molotov/molotov_fire.wav", VOL_NORM, ATTN_NORM, 0, PITCH_NORM);

	engfunc(EngFunc_SetModel, ent, "models/molotov/w_broke_molotov.mdl");

	random_fire(iOrigin, ent2);
	radius_damage(owner, fOrigin, get_pcvar_float(pMlDamage), get_pcvar_float(pMlRadius), DMG_BLAST);

	new Float:FireTime = get_pcvar_float(pFireTime);

	if (++g_Molotov_offset[owner] == MOLOTOV_HARD_LIMIT) g_Molotov_offset[owner] = 0;

	set_task(0.2, "fire_damage", MOLOTOV_TASKID_BASE1 + (MOLOTOV_TASKID_OFFSET * (owner - 1)) + g_Molotov_offset[owner], param, 6, "a", floatround(FireTime / 0.2, floatround_floor));
	set_task(1.0, "fire_sound", MOLOTOV_TASKID_BASE2 + (MOLOTOV_TASKID_OFFSET * (owner - 1)) + g_Molotov_offset[owner], param, 6, "a", floatround(FireTime) - 1);
	set_task(FireTime, "fire_stop", MOLOTOV_TASKID_BASE3 + (MOLOTOV_TASKID_OFFSET * (owner - 1)) + g_Molotov_offset[owner], param, 6);
}

public fire_sound(param[]) emit_sound(param[1], CHAN_AUTO, "molotov/molotov_fire.wav", VOL_NORM, ATTN_NORM, 0, PITCH_NORM);

public fire_stop(param[]) {
	g_g = 0;

	if (pev_valid(param[0])) { engfunc(EngFunc_RemoveEntity, param[0]); }
	if (pev_valid(param[1])) { engfunc(EngFunc_RemoveEntity, param[1]); }

	if ((last_Molotov_ent = (param[0])))	last_Molotov_ent = 0;
}

public fire_damage(param[]) {
	new iOrigin[3], Float:fOrigin[3];
	iOrigin[0] = param[3];
	iOrigin[1] = param[4];
	iOrigin[2] = param[5];

	random_fire(iOrigin, param[1]);

	IVecFVec(iOrigin, fOrigin);
	radius_damage(param[2], fOrigin, get_pcvar_float(pFireDmg), get_pcvar_float(pMlRadius), DMG_BURN, 0);
}

stock radius_damage(attacker, Float:origin[3], Float:damage, Float:range, dmgtype, calc = 1) {
	new Float:pOrigin[3], Float:dist, Float:tmpdmg;
	new i, ateam = get_user_team(attacker), iFF = get_pcvar_num(pFriendlyFire);

	while (i++ < g_MaxPlayers) {
		if (!is_user_alive(i)) continue;

		if (!iFF && ateam == get_user_team(i)) continue;

		pev(i, pev_origin, pOrigin);
		dist = get_distance_f(origin, pOrigin);

		if (dist > range) continue;

		if (calc) tmpdmg = damage - (damage / range) * dist;
		else tmpdmg = damage;

		if (pev(i, pev_health) < tmpdmg) kill(attacker, i);
		else fm_fakedamage(i, "molotov", tmpdmg, dmgtype);
	}

	while ((i = engfunc(EngFunc_FindEntityInSphere, i, origin, range))) {	// warning 211: possibly unintended assignment
		if (pev(i, pev_takedamage)) {
			if (calc) {
				pev(i, pev_origin, pOrigin);
				tmpdmg = damage - (damage / range) * get_distance_f(origin, pOrigin);
			} else tmpdmg = damage;
			fm_fakedamage(i, "molotov", tmpdmg, dmgtype);
		}
	}
}

stock random_fire(Origin[3], ent) {
	new range = get_pcvar_num(pMlRadius);
	new iOrigin[3];

	for (new i = 1; i <= 5; i++) {
		g_g = 1;

		iOrigin[0] = Origin[0] + random_num(-range, range);
		iOrigin[1] = Origin[1] + random_num(-range, range);
		iOrigin[2] = Origin[2];
		iOrigin[2] = ground_z(iOrigin, ent);

		while (get_distance(iOrigin, Origin) > range) {
			g_g++;
#if defined MOLOTOV_DEBUG
			//log_amx("[MC] random_fire ent(%d) i(%d) g_g(%d)", ent, i, g_g);
#endif
			iOrigin[0] = Origin[0] + random_num(-range, range);
			iOrigin[1] = Origin[1] + random_num(-range, range);
			iOrigin[2] = Origin[2];

			if (g_g >= ANTI_LAGG) iOrigin[2] = ground_z(iOrigin, ent, 1);
			else iOrigin[2] = ground_z(iOrigin, ent);
		}

		new rand = random_num(5, 15);

		message_begin(MSG_BROADCAST, SVC_TEMPENTITY);
		write_byte(TE_SPRITE);
		write_coord(iOrigin[0]);
		write_coord(iOrigin[1]);
		write_coord(iOrigin[2] + rand * 5);
		write_short(firespr);
		write_byte(rand);
		write_byte(100);
		message_end();

		if (!(i % 4)) {	// Smoke every 4th flame
			message_begin(MSG_BROADCAST, SVC_TEMPENTITY);
			write_byte(TE_SMOKE);
			write_coord(iOrigin[0]);
			write_coord(iOrigin[1]);
			write_coord(iOrigin[2] + 120);
			write_short(smokespr[random_num(0, 1)]);
			write_byte(random_num(10, 30));
			write_byte(random_num(10, 20));
			message_end();
		}
	}
}

stock kill(k, v) {
	user_silentkill(v);

	new kteam = get_user_team(k);
	new vteam = get_user_team(v);

	new kfrags = get_user_frags(k) + 1;
	new kdeaths = get_user_deaths(k);
	if (kteam == vteam) kfrags = get_user_frags(k) - 2;

	new vfrags = get_user_frags(v);
	new vdeaths = get_user_deaths(v);

	message_begin(MSG_ALL, gmsgScoreInfo);
	write_byte(k);
	write_short(kfrags);
	write_short(kdeaths);
	write_short(0);
	write_short(kteam);
	message_end();

	message_begin(MSG_ALL, gmsgScoreInfo);
	write_byte(v);
	write_short(vfrags + 1);
	write_short(vdeaths);
	write_short(0);
	write_short(vteam);
	message_end();

	message_begin(MSG_ALL, gmsgDeathMsg, {0,0,0}, 0);
	write_byte(k);
	write_byte(v);
	write_byte(0);
	write_string("molotov");
	message_end();

	g_frags[k]++;

	if (kteam != vteam) cs_set_user_money(k, cs_get_user_money(k) + 300);
	else cs_set_user_money(k, cs_get_user_money(k) - 300);
}

stock ground_z(iOrigin[3], ent, skip = 0, iRecursion = 0) {

#if defined MOLOTOV_DEBUG
	new iEntValid = pev_valid(ent);
	if (iRecursion > 0) log_amx("[MC] ground_z ent(%d) iEntValid(%d) skip(%d) iRecursion(%d)", ent, iEntValid, skip, iRecursion);
#endif
	iOrigin[2] += random_num(5, 80);

	if (!pev_valid(ent)) {	// Fix for: Run time error 10: native error (native "set_pev")
		return iOrigin[2];
	}

	new Float:fOrigin[3];
	IVecFVec(iOrigin, fOrigin);
	set_pev(ent, pev_origin, fOrigin);

	engfunc(EngFunc_DropToFloor, ent);

	if (!skip && !engfunc(EngFunc_EntIsOnFloor, ent)) {
		if (iRecursion >= ANTI_LAGG) skip = 1;
#if defined MOLOTOV_DEBUG
		log_amx("[MC] ground_z ++iRecursion(%d)", ++iRecursion);
		return ground_z(iOrigin, ent, skip, iRecursion);
#else
		return ground_z(iOrigin, ent, skip, ++iRecursion);
#endif
	}

	pev(ent, pev_origin, fOrigin);

	return floatround(fOrigin[2]);
}

stock reset_molotovs() {
	new ent = g_MaxPlayers;
	while ((ent = engfunc(EngFunc_FindEntityByString, ent, "model", "models/molotov/w_molotov.mdl")))	engfunc(EngFunc_SetModel, ent, "models/w_smokegrenade.mdl");
}

stock set_molotovs() {
	new ent = g_MaxPlayers;
	while ((ent = engfunc(EngFunc_FindEntityByString, ent, "model", "models/w_smokegrenade.mdl")))	engfunc(EngFunc_SetModel, ent, "models/molotov/w_molotov.mdl");
}

// This will run at event New Round if enabled
public show_molotov_menu(id) {
	new menu[192];

	// Get a custom menu title with the price
	// When done it should look something like this:
	// Buy Molotov Cocktail ($1200)...
	new menu_title_text[120], the_molotov_price[7];
	get_cvar_string("molotov_price", the_molotov_price, 6);
	strcat(menu_title_text, "Buy Molotov Cocktail ($", 40);
	strcat(menu_title_text, the_molotov_price, 40);
	strcat(menu_title_text, ")?^n^n1. Yes, I will burn them all...^n2. No, I will kill in some other way...^n^n0. EXIT MENU", 119);

	format(menu, 191, menu_title_text);

	// This shows the menu for 30 seconds, I tried first with get_cvar_num("mp_buytime")*60 , but it didn't work well
	// when using 0.5 as mp_buytime. If you like, just change the time below
	show_menu(id, MOLOTOV_MENU_KEYS, menu, 30);

	return PLUGIN_HANDLED;
}

//Our menu function will get the player id and the key they pressed
public giveMolotov(id, key) {
	//key will start at zero
	if (key == 0) buy_molotov(id);
	else if (key == 1) client_print(id, print_center, ">You have chosen not to buy a Molotov Coctail<");
	else client_print(id, print_center, ">You have choosen to exit the molotov menu...<");
}
Pentru ajutor, faceți cerere bine detaliată, completând și respectând modelul corespunzător.
Nu-mi mai dați cereri doar pentru a mă avea în lista de prieteni.
Dacă te ajut, și mă ignori/etc > te adaug în „foe”.
Aveți grijă la cei ce încearcă să mă copieze sau să dea drept mine..Puteți lua legătura cu mine prin STEAM dacă aveți o problemă/nelămurire în acest caz! Cont de forum am doar aici.
În cazul în care utilizați ceva din ce am postat(ex: aici), e bine să fiți la curent cu modificările aduse și de aici, iar dacă sunt ceva probleme nu ezitați să luați legătura cu mine. Actualizarea unor coduri nu se vor afișa public, doar dacă se găsește ceva critic/urgent de remediat, unele fiind coduri vechi iar unele refăcute chiar recent dar private.
* Nume pe cs1.6: eVoLuTiOn \ Nume vechi: eVo
* Atelierul meu - post2819572.html#p2819572 (închis, click link ca să vedeți de ce)
diavolu111
Membru, skill +1
Membru, skill +1
Posts: 419
Joined: 11 Oct 2014, 18:18
Detinator Steam: Da
Fond eXtream: 0
Location: Alba Iulia
Has thanked: 28 times
Been thanked: 6 times
Contact:

13 Mar 2020, 13:50

la fel ramane grenada pe jos si nu se intampla nimic

la vip nu ma refer ca nu merge, merge bine, doar ca nu limiteaza numarul de molotovuri petru vip... "#define MAXIM_GRENADE_VIP 3" ca vip poti cumpara cate molotovuri vrei cu toate ca limita e pusa la 3 molotovuri :)

cat despre erori, nu apare nimic in log... este curat
Post Reply

Return to “Modificari pluginuri”

  • Information
  • Who is online

    Users browsing this forum: No registered users and 4 guests