#include < amxmodx >
#include < amxmisc >
#include < csdm_object >
#include < engine>
#pragma semicolon 1
#define _VERSION "#0.91"
#define DMG_AWARD random_num(3, 10) // Награда за урон
#define UPDATE_DELAY 15.0 // Через сколько можно обновлять
#define BUILD_TIME 10.03 // Время на постройку
#define UPGRADE_TIME 3.025 // Время обновления
const MAX_SENTRY = 5; // Лимит
#define PrintModel "models/csdm/sentrygun_blueprint.mdl"
#define GibsMdl "models/csdm/sentrygun_gibs.mdl"
#define RoketMdl "models/csdm/sentrygun_rockets.mdl"
#define WEAPON_LIST "weapon_sentrygun"
enum _:eAnimSentry{
_IDLE = 0, _FIRE, _FIRE_ALT, _FIRE_ROKET
};
enum _:eSentrySound {
Build, Idle, Fire, Upgrade, Roket, Explode
};
new szSentryModels[eLevelList][] = {
"models/csdm/sentrygun1_low.mdl",
"models/csdm/sentrygun2_low.mdl",
"models/csdm/sentrygun3_low.mdl"
};
new szUpgradeModels[eLevelList][] = {
"models/csdm/sentrygun1_heavy.mdl",
"models/csdm/sentrygun2_heavy.mdl",
"models/csdm/sentrygun3_heavy.mdl"
};
new szPlayerBoxModel[][] = {
"models/csdm/p_box_red.mdl",
"models/csdm/p_box_blue.mdl"
};
new szViewBoxModel[][] = {
"models/csdm/v_box_red.mdl",
"models/csdm/v_box_blue.mdl"
};
new szSentrySound[eSentrySound][] = {
"csdm/sentry_finish.wav", "csdm/sentry_spot_client.wav",
"csdm/sentry_shoot3.wav", "csdm/sentry_generate_metal.wav",
"csdm/sentry_rocket.wav", "csdm/sentry_explode.wav"
};
// Health = get_players() * (koef * Level)
const HealthKoef = 50; // Hp пушки зависит от числа игроков
new g_CostUpgrade[ 3 ] = { 10, 11, 12 }; // Цена постройки
new Float:g_Damage[ 3 ] = { 10.0, 15.0, 25.0 }; // Урон наносимый
new Float:g_Reaction[ 3 ] = { 0.5, 0.3, 0.1 }; // Время реагирования
new Float:g_FireTime[ 3 ] = { 0.6, 0.3, 0.1 }; // Время между выстрелами
const Float:RADIUS_DAMAGE_ROKET = 200.0; // Радиус взрыва рокет
const Float:DAMAGE_ROKET = 80.0; // Урон от рокет
#define REFERENCE_WEAPON "weapon_tmp"
#define _ClassName "Sentry"
const Float:SENTRY_VEC_Z_OFSET = 45.0;
const Float:SIZE = 16.0;
const ITEM_POSITION = 5;
new HookChain:g_DeathNoticeHook;
new g_Smoke;
public plugin_init()
{
register_plugin
(
"[AMXX] Sentry TF2",
_VERSION,
"Flymic24"
);
RegisterHam(Ham_TraceAttack, "info_target", "HamHook_Sentry_TraceAttack", false);
RegisterHam(Ham_Killed, "info_target", "HamHook_Sentry_Killed", false);
RegisterHookChain(RG_CBasePlayer_UseEmpty, "HamHook_Sentry_Use", .post = true);
RegisterHookChain(RG_CBasePlayerWeapon_DefaultDeploy, "CBasePlayerWeapon_DefaultDeploy", false);
DisableHookChain(g_DeathNoticeHook = RegisterHookChain(RG_CSGameRules_DeathNotice, "CSGameRules_DeathNotice", true));
RegisterHookChain(RG_CBasePlayer_Spawn, "CBasePlayer_OnSpawnEquip", true);
RegisterHam(Ham_Item_PostFrame, REFERENCE_WEAPON, "HamHook_Item_PostFrame", false);
RegisterHam(Ham_Weapon_PrimaryAttack, REFERENCE_WEAPON, "HamHook_Item_PrimaryAttack", false);
register_message(get_user_msgid("DeathMsg"), "Msg_DeathMsg");
RegisteFunc(REFERENCE_WEAPON);
AMMO_ID = rg_add_ammo_registry(WEAPON_LIST);
iKey = engfunc(EngFunc_AllocString, _ClassName);
}
public plugin_precache(){
precache_model(PrintModel);
precache_model(GibsMdl);
precache_model(RoketMdl);
for(new i = _Level1; i < eLevelList; i++){
precache_model(szSentryModels[i]);
precache_model(szUpgradeModels[i]);
}
for(new i = 0; i < sizeof(szPlayerBoxModel); i++){
precache_model(szPlayerBoxModel[i]);
precache_model(szViewBoxModel[i]);
if(get_cvar_num("sv_auto_precache_sounds_in_models") == 0) {
PRECACHE_MODEL2(szViewBoxModel[i]);
}
}
for(new i = 0; i < sizeof(szSentrySound); i++) {
precache_sound(szSentrySound[i]);
}
PRECACHE_WEAPONLIST(WEAPON_LIST);
g_Smoke = precache_model("sprites/steam1.spr");
}
/* *****************
Give custom Sentry
********************/
public CBasePlayer_OnSpawnEquip(const iPlayer){
if (EquipDelay > 0.0)
set_task(EquipDelay, "GiveEquip", iPlayer);
else
GiveEquip(iPlayer);
}
public GiveEquip(iPlayer) {
GiveObject(iPlayer, REFERENCE_WEAPON, iKey, AMMO_ID, MAX_SENTRY);
}
public CBasePlayerWeapon_DefaultDeploy(const iItem, szViewModel[], szWeaponModel[], iAnim, szAnimExt[], skiplocal) {
if(!IsCustomItem(iItem))
return HC_CONTINUE;
new iPlayer;
if(!(iPlayer = get_member(iItem, m_pPlayer)) || !is_user_connected(iPlayer))
return HC_CONTINUE;
new iTeam = get_member(iPlayer, m_iTeam) - 1;
SetHookChainArg(2, ATYPE_STRING, szViewBoxModel[iTeam]);
SetHookChainArg(3, ATYPE_STRING, szPlayerBoxModel[iTeam]);
SetHookChainArg(4, ATYPE_INTEGER, _DRAW);
return HC_CONTINUE;
}
/*******************
Ham hook Sentry
********************/
public Default_Item_Holster(const iItem, const iPlayer) {
// Code
}
public Default_Item_AttachToPlayer(const iItem, const iPlayer) {
SetObjectWeaponList(iItem, iPlayer, AMMO_ID, WEAPON_LIST, MAX_SENTRY, ITEM_POSITION);
}
public HamHook_Item_PostFrame(const iItem){
if(!IsCustomItem(iItem))
return HAM_IGNORED;
new iPlayer;
if(!(iPlayer = get_member(iItem, m_pPlayer)) || !is_user_connected(iPlayer))
return HAM_IGNORED;
if(get_member(iPlayer, m_iAccount) >= g_CostUpgrade[_Level1] && get_member(iItem, m_Weapon_iDefaultAmmo) > 0) {
rg_add_account(iPlayer, g_CostUpgrade[_Level1]);
rg_add_account(iPlayer, -g_CostUpgrade[_Level1]);
}
new Float:vecSrc[eCoord], Float:vecAiming[eCoord];
GetPlantOrigin(iPlayer, vecSrc, vecAiming);
engfunc(EngFunc_TraceLine, vecSrc, vecAiming, IGNORE_MISSILE|IGNORE_GLASS|IGNORE_MONSTERS, iPlayer, 0);
new Float:flFraction; get_tr2(0, TR_flFraction, flFraction);
new iSentry = iObjectID[iPlayer];
if (flFraction >= 1.0 || !is_user_alive(iPlayer)) {
if(!is_nullent(iSentry)) {
UTIL_KillEntity(iSentry);
}
iObjectID[iPlayer] = NULLENT;
return HAM_IGNORED;
}
else if(flFraction < 1.0) {
if(is_nullent(iSentry)) {
iObjectID[iPlayer] = iSentry = SpawnObject(_ClassName, PrintModel, Float:{-SIZE, -SIZE, 0.0}, Float:{SIZE, SIZE, 55.0});
}
new Float:fVecEnd[eCoord], Float:fVecNormal[eCoord], Float:fAngles[eCoord];
get_tr2(0, TR_vecEndPos, fVecEnd);
get_tr2(0, TR_vecPlaneNormal, fVecNormal);
xs_vec_mul_scalar(fVecNormal, 1.0, fVecNormal);
xs_vec_add(fVecEnd, fVecNormal, fVecEnd);
engfunc(EngFunc_SetOrigin, iSentry, fVecEnd);
if (fVecNormal[2] == 1.0 && CheckLocation(iSentry, fVecEnd, SIZE * 2, SENTRY_VEC_Z_OFSET)) {
set_entvar(iSentry, var_sequence, _IDLE);
get_entvar(iPlayer, var_angles, fAngles);
fAngles[1] -= 180.0;
fAngles[0] += 12.0;
}
else {
set_entvar(iSentry, var_sequence, _DRAW);
vector_to_angle(fVecNormal, fAngles);
fAngles[0] -= 90.0;
}
set_entvar(iSentry, var_angles, fAngles);
}
return HAM_IGNORED;
}
public HamHook_Item_PrimaryAttack(const iItem){
if(!IsCustomItem(iItem))
return HAM_IGNORED;
new iPlayer;
if(!(iPlayer = get_member(iItem, m_pPlayer)) || !is_user_connected(iPlayer))
return HAM_IGNORED;
new iSentry;
if (!(iSentry = iObjectID[iPlayer]) || is_nullent(iSentry))
return HAM_SUPERCEDE;
set_member(iItem, m_Weapon_flNextPrimaryAttack, 1.0);
if (get_entvar(iSentry, var_sequence) == _DRAW){
client_print(iPlayer, print_center, "Здесь строить нельзя");
return HAM_SUPERCEDE;
}
new iClip = get_member(iPlayer, m_rgAmmo, AMMO_ID);
if (--iClip < 0) {
client_print(iPlayer, print_center, "Более нельзя ставить");
return HAM_SUPERCEDE;
}
if(get_member(iPlayer, m_iAccount) < g_CostUpgrade[_Level1]) {
client_print(iPlayer, print_center, "Не достаточно средств: %i", g_CostUpgrade[_Level1]);
return HAM_SUPERCEDE;
}
set_member(iItem, m_Weapon_iDefaultAmmo, iClip);
set_member(iPlayer, m_rgAmmo, iClip, AMMO_ID);
BuildObject(iPlayer, iSentry, BUILD_TIME, szSentrySound[Build], _IDLE, UPDATE_DELAY, szUpgradeModels[_Level1]);
set_entvar(iSentry, var_controller, 0, POS_X);
set_entvar(iSentry, var_controller, 127, POS_Y);
set_entvar(iSentry, var_angles, Float:{0.0, 0.0, 0.0});
set_entvar(iSentry, object_target, NULLENT);
rg_add_account(iPlayer, -g_CostUpgrade[_Level1]);
return HAM_SUPERCEDE;
}
/**********************************
Brain to Sentry
**********************************/
#define UPDATE_TIME 0.05
public Object_Think(const iEnt) {
if (is_nullent(iEnt))
return;
new Float:fGameTime = get_gametime();
new iTeam = get_entvar(iEnt, var_team);
new iLevel = get_entvar(iEnt, object_level);
new iOwner = get_entvar(iEnt, object_owner);
if(!is_user_alive(iOwner) || get_member(iOwner, m_iTeam) != iTeam) {
UTIL_KillEntity(iEnt);
return;
}
SetObjectInfoAim(fGameTime, iTeam, iEnt);
if (get_entvar(iEnt, object_active_time) > fGameTime) {
set_entvar(iEnt, var_nextthink, fGameTime + UPDATE_TIME);
return;
}
switch(get_entvar(iEnt, object_status)) {
case _BUILDING: {
engfunc(EngFunc_SetModel, iEnt, szSentryModels[iLevel]);
engfunc(EngFunc_SetSize, iEnt, Float:{-SIZE, -SIZE, 0.0}, Float:{SIZE, SIZE, 55.0});
new Float:fHealth = GetHealthSentry(iLevel);
set_entvar(iEnt, var_takedamage, DAMAGE_YES);
set_entvar(iEnt, var_health, fHealth);
set_entvar(iEnt, var_max_health, fHealth);
set_entvar(iEnt, object_status, _SEARCH);
}
case _SEARCH: {
new iController1 = get_entvar(iEnt, var_controller, POS_X);
if (++iController1 > 255) iController1 -= 255;
set_entvar(iEnt, var_controller, iController1, POS_X);
set_entvar(iEnt, var_controller, 127, POS_Y);
UTIL_Animation(iEnt, _IDLE);
new iNewTarget = GetSentryTarget(iEnt);
if (is_user_connected(iNewTarget)) {
SentryTurnToTarget(iEnt, iNewTarget);
rh_emit_sound2(iEnt, 0, CHAN_STATIC, szSentrySound[Idle]);
set_entvar(iEnt, object_target, iNewTarget);
set_entvar(iEnt, object_status, _ACTIVE);
set_entvar(iEnt, var_nextthink, fGameTime + g_Reaction[iLevel]);
return;
}
}
case _ACTIVE: {
new iTarget = get_entvar(iEnt, object_target);
if (!is_user_alive(iTarget) || !UTIL_IsVisible(iTarget, iEnt, SENTRY_VEC_Z_OFSET) || IsUseShield(iTarget)) {
set_entvar(iEnt, object_target, NULLENT);
set_entvar(iEnt, object_status, _SEARCH);
}
else
{
new iLevel = get_entvar(iEnt, object_level);
SentryTurnToTarget(iEnt, iTarget);
if (get_entvar(iEnt, object_state) != _FIRE_ROKET)
UTIL_Animation(iEnt);
if (fGameTime > get_entvar(iEnt, var_fuser2)) {
UTIL_Animation(iEnt, _FIRE);
DefaultAttack(iEnt, iOwner, iTarget);
set_entvar(iEnt, object_state, _FIRE);
set_entvar(iEnt, var_fuser2, fGameTime + g_FireTime[iLevel]);
}
if (iLevel == _Level3) {
if (fGameTime > get_entvar(iEnt, var_fuser3)) {
UTIL_Animation(iEnt, _FIRE_ROKET);
FireRoket(iEnt, iOwner, iTarget, 600.0);
set_entvar(iEnt, object_state, _FIRE_ROKET);
set_entvar(iEnt, var_fuser2, fGameTime + 1.53);
set_entvar(iEnt, var_fuser3, fGameTime + 5.0);
}
}
}
}
}
set_entvar(iEnt, var_nextthink, fGameTime + UPDATE_TIME);
}
public HamHook_Sentry_Use(const pPlayer) {
new iEnt, iBody;
get_user_aiming(pPlayer, iEnt, iBody, floatround(PLANT_RADIUS));
if (!IsCustomObject(iEnt))
return;
if(get_member(pPlayer, m_iTeam) != get_entvar(iEnt, var_team))
return;
new iLevel = get_entvar(iEnt, object_level);
if (++iLevel >= eLevelList){
return;
}
UpgradeObject(pPlayer, iEnt, iLevel, _IDLE, UPGRADE_TIME, UPDATE_DELAY, g_CostUpgrade[iLevel], szSentrySound[Upgrade], szUpgradeModels[iLevel]);
if (iLevel == _Level3) {
set_entvar(iEnt, var_fuser3, get_gametime() + UPGRADE_TIME + 5.0);
}
}
public Sentry_RoketTouch(const iEnt, const iOther){
if (is_nullent(iEnt))
return;
new Float:fVecOrigin[eCoord]; get_entvar(iEnt, var_origin, fVecOrigin);
UTIL_TE_EXPLOSION(fVecOrigin);
new iOwner = get_entvar(iEnt, var_owner);
new iVictim = NULLENT;
while((iVictim = engfunc(EngFunc_FindEntityInSphere, iVictim, fVecOrigin, RADIUS_DAMAGE_ROKET)))
{
if(!is_user_alive(iVictim)) continue;
if(get_member(iVictim, m_iTeam) == get_member(iOwner, m_iTeam)) continue;
ExecuteHamB(Ham_TakeDamage, iVictim, iEnt, iOwner, DAMAGE_ROKET, DMG_GRENADE);
}
// rg_dmg_radius(fVecOrigin, iEnt, iOwner, DAMAGE_ROKET, RADIUS_DAMAGE_ROKET, 0, DMG_GRENADE);
UTIL_KillEntity(iEnt);
}
public HamHook_Sentry_Killed(const iVictim, const iAttacker){
if (is_nullent(iVictim))
return HAM_IGNORED;
if (!IsCustomObject(iVictim))
return HAM_IGNORED;
rh_emit_sound2(iVictim, 0, CHAN_STATIC, szSentrySound[Explode]);
new Float:fVecOrigin[eCoord]; get_entvar(iVictim, var_origin, fVecOrigin);
UTIL_TE_EXPLOSION(fVecOrigin);
new iOwner = get_entvar(iVictim, object_owner);
if (is_user_connected(iOwner)) {
set_member(iOwner, m_rgAmmo, get_member(iOwner, m_rgAmmo, AMMO_ID) + 1, AMMO_ID);
}
CObject_Gibs(iVictim, GibsMdl, random_num(0, 11), get_entvar(iVictim, var_skin));
return HAM_IGNORED;
}
public HamHook_Sentry_TraceAttack(iVictim, iAttacker, Float:flDamage, Float:flDirection[3], iTrace, iDamageBits){
if (!is_user_connected(iAttacker))
return HAM_IGNORED;
if (!IsCustomObject(iVictim))
return HAM_IGNORED;
if (get_entvar(iVictim, var_takedamage) != DAMAGE_YES)
return HAM_SUPERCEDE;
new Float:flEndOrigin[eCoord]; get_tr2(iTrace, TR_vecEndPos, flEndOrigin);
UTIL_TE_SPARKS(flEndOrigin);
if(get_entvar(iVictim, var_team) == get_member(iAttacker, m_iTeam) /*&& iAttacker != get_entvar(iVictim, object_owner)*/)
return HAM_SUPERCEDE;
rg_add_account(iAttacker, DMG_AWARD);
return HAM_IGNORED;
}
public ShowObjectInfoAim(const iPlayer, const iEnt, Float:fGameTime) {
new Float:iHealth = get_entvar(iEnt, var_health);
new iLevel = get_entvar(iEnt, object_level);
new iOwner = get_entvar(iEnt, object_owner);
new iKill = get_entvar(iEnt, object_data1);
new iTeam = get_entvar(iEnt, var_team);
set_dhudmessage(iTeam == _:TEAM_TERRORIST ? 120 : 0, 0, iTeam == _:TEAM_CT ? 255 : 0, -1.0, 0.35, 0, 0.0, 1.1, 0.0, 0.0);
show_dhudmessage(iPlayer, fmt("Владелец: %n^nПрочность: %i^nУровень: %i Убийств: %i", iOwner, floatround(iHealth), iLevel + 1, iKill));
if (iLevel < eLevelList - 1) {
new Float:fUpdateTime; get_entvar(iEnt, object_update_time, fUpdateTime);
if (fGameTime < fUpdateTime)
show_dhudmessage(iPlayer, fmt("^n^n^nАпгрейд: %i$ Update: %i", g_CostUpgrade[++iLevel], floatround(fUpdateTime - fGameTime)));
else
show_dhudmessage(iPlayer, fmt("^n^n^nАпгрейд: %i$ Update: Нажмите на <E>", g_CostUpgrade[++iLevel]));
}
}
DefaultAttack(const iEnt, const iOwner, const iTarget) {
if (is_nullent(iEnt))
return;
enum _:eData{
Entity = 0, Target
};
new Float:fOrigin[eData][eCoord];
get_entvar(iEnt, var_origin, fOrigin[Entity]); fOrigin[Entity][2] += SENTRY_VEC_Z_OFSET;
get_entvar(iTarget, var_origin, fOrigin[Target]);
new iLevel = get_entvar(iEnt, object_level);
switch(iLevel)
{
case _Level1: UTIL_TE_TRACER(fOrigin[Entity], fOrigin[Target]);
default:
{
fOrigin[Entity][1] += 30.0;
UTIL_TE_TRACER(fOrigin[Entity], fOrigin[Target]);
fOrigin[Entity][1] -= 60.0;
UTIL_TE_TRACER(fOrigin[Entity], fOrigin[Target]);
}
}
rh_emit_sound2(iEnt, 0, CHAN_STATIC, szSentrySound[Fire]);
// engfunc(EngFunc_EmitAmbientSound, iEnt, pos_ent/*coord*/, szSentrySound[Fire], VOL_NORM /*0.5*/, ATTN_NORM, 0, PITCH_NORM);
if (get_entvar(iTarget, var_armorvalue) > g_Damage[iLevel])
set_entvar(iTarget, var_armorvalue, get_entvar(iTarget, var_armorvalue) - g_Damage[iLevel]);
else
ExecuteHamB(Ham_TakeDamage, iTarget, iEnt, iOwner, g_Damage[iLevel], DMG_GRENADE);
if(!is_user_alive(iTarget)) {
set_entvar(iEnt, object_data1, get_entvar(iEnt, object_data1) + 1);
}
}
FireRoket(const iEnt, const iOwner, const iTarget, Float:fSpeed) {
enum _:eData{
Entity = 0, Target, Velocity, Angles
};
rh_emit_sound2(iEnt, 0, CHAN_STATIC, szSentrySound[Roket]);
// engfunc(EngFunc_EmitAmbientSound, iEnt, pos_ent/*coord*/, szSentrySound[Roket], VOL_NORM /*0.5*/, ATTN_NORM, 0, PITCH_NORM);
new Float:fVecOrigin[eData][eCoord];
get_entvar(iTarget, var_origin, fVecOrigin[ Target ]);
get_entvar(iEnt, var_origin, fVecOrigin[ Entity ]); fVecOrigin[Entity][2] += SENTRY_VEC_Z_OFSET;
get_entvar(iEnt, var_angles, fVecOrigin[ Angles ]);
angle_vector(fVecOrigin[ Angles ], ANGLEVECTOR_FORWARD, fVecOrigin[ Angles ]);
xs_vec_mul_scalar(fVecOrigin[ Angles ], 15.0, fVecOrigin[ Angles ]);
xs_vec_add(fVecOrigin[ Entity ], fVecOrigin[ Angles ], fVecOrigin[ Entity ]);
message_begin(MSG_BROADCAST, SVC_TEMPENTITY);
write_byte(TE_SMOKE);
write_coord_f(fVecOrigin[ Entity ][0]);
write_coord_f(fVecOrigin[ Entity ][1]);
write_coord_f(fVecOrigin[ Entity ][2]);
write_short(g_Smoke);
write_byte(random_num(5, 8));
write_byte(5);
message_end();
new ent;
if(!(ent = rg_create_entity("info_target")) || is_nullent(ent))
return;
set_entvar(ent, var_classname, "roket");
engfunc(EngFunc_SetModel, ent, RoketMdl);
engfunc(EngFunc_SetSize, ent, Float:{ -5.0, -5.0, -5.0 }, Float:{ 5.0, 5.0, 5.0 });
engfunc(EngFunc_SetOrigin, ent, fVecOrigin[ Entity ]);
xs_vec_sub(fVecOrigin[ Target ], fVecOrigin[ Entity ], fVecOrigin[ Target ]);
xs_vec_normalize(fVecOrigin[ Target ], fVecOrigin[ Velocity ]);
xs_vec_mul_scalar(fVecOrigin[ Velocity ], fSpeed, fVecOrigin[ Velocity ]);
vector_to_angle(fVecOrigin[ Velocity ], fVecOrigin[ Angles ]);
set_entvar(ent, var_movetype, MOVETYPE_FLY);
set_entvar(ent, var_angles, fVecOrigin[ Angles ]);
set_entvar(ent, var_velocity, fVecOrigin[ Velocity ]);
set_entvar(ent, var_solid, SOLID_TRIGGER);
set_entvar(ent, var_owner, iOwner);
SetTouch(ent, "Sentry_RoketTouch");
UTIL_Animation(ent, _IDLE);
}
/*******************
Kill Message
********************/
public CSGameRules_DeathNotice(const iVictim, const iAttacker, inflictor) {
rh_update_user_info(iAttacker);
DisableHookChain(g_DeathNoticeHook);
}
public Msg_DeathMsg() {
new szClassName[MAX_NAME_LENGTH]; get_msg_arg_string(4, szClassName, charsmax(szClassName));
if(!equali(szClassName, _ClassName) && !equali(szClassName, "roket"))
return;
new iAttacker = get_msg_arg_int(1);
new szName[MAX_NAME_LENGTH]; get_user_name(iAttacker, szName, charsmax(szName));
EnableHookChain(g_DeathNoticeHook);
set_user_fake_name(iAttacker, fmt("%.14s [Sentry Gun]", szName));
set_msg_arg_string(4, "teammate");
}
/*******************
Stock
********************/
stock GetSentryTarget(const iEntity) {
new iTarget = NULLENT, Float:fLen = 0.0, Float:fLenMax = 9999.0;
new iTeam = get_entvar(iEntity, var_team);
for (new id = 1; id <= MaxClients; id++) {
if (!is_user_alive(id)) continue;
if (get_member(id, m_iTeam) == iTeam) continue;
if (!UTIL_IsVisible(id, iEntity, SENTRY_VEC_Z_OFSET)) continue;
if (IsUseShield(id)) continue;
fLen = entity_range(id, iEntity);
if(fLen < fLenMax) {
fLenMax = fLen;
iTarget = id;
}
}
return iTarget;
}
stock Float:GetHealthSentry(Level) {
return float(get_playersnum_ex(GetPlayers_ExcludeHLTV) * (HealthKoef * ++Level));
}
stock SentryTurnToTarget(const iSentry, const iTarget)
{
enum _:eData {
Entity, Target, Angles
};
new Float:fVecOrigin[eData][eCoord];
get_entvar(iSentry, var_origin, fVecOrigin[ Entity ]); fVecOrigin[Entity][2] += SENTRY_VEC_Z_OFSET;
get_entvar(iSentry, var_angles, fVecOrigin[Angles]);
get_entvar(iTarget, var_origin, fVecOrigin[ Target ]);
new Float:fDirection[eCoord];
fDirection[0] = fVecOrigin[ Target ][0] - fVecOrigin[ Entity ][0];
fDirection[1] = fVecOrigin[ Target ][1] - fVecOrigin[ Entity ][1];
fDirection[2] = fVecOrigin[ Target ][2] - fVecOrigin[ Entity ][2];
new Float:fShootAngles[3]; vector_to_angle(fDirection, fShootAngles);
new Float:fRotatorAngle = fShootAngles[1] - fVecOrigin[Angles][1];
if(fRotatorAngle < 0.0) {
fRotatorAngle += 360.0;
}
set_controller(iSentry, POS_X, fRotatorAngle);
set_controller(iSentry, POS_Y, -fShootAngles[0] + 360.0);
}
#include < amxmodx >
#include < csdm_object >
#pragma semicolon 1
#define _VERSION "#0.8.2"
#define DMG_AWARD random_num(3, 10) // Награда за урон
#define UPDATE_DELAY 7.0 // Через сколько можно обновлять
#define BUILD_TIME 10.0 // Время на постройку
#define UPGRADE_TIME 1.23 // Время обновления
#define MAX_DISPENCER 3 // Лимит
#define PrintModel "models/csdm/dispenser_blueprint.mdl"
#define GibsMdl "models/csdm/dispenser_gibs.mdl"
#define HealthSpr "sprites/csdm/dispenser_heal.spr"
#define ActivateSound "buttons/button9.wav"
#define WEAPON_LIST "weapon_dispenser"
#define SIZE 16.0
new szClassActive[][16] = { // Классы обьектов
"Sentry", "DispenserHP", "_tripmine"
};
const POSITION_NUM = 2;
const Float:MAX_HP = 255.0; // Максимум до скольки пополнять хп
const Float:MAX_AP = 100.0; // Максимум до скольки пополнять броню
new szDispenserModels[eLevelList][] = {
"models/csdm/dispenser1_light.mdl",
"models/csdm/dispenser2_light.mdl",
"models/csdm/dispenser3_light.mdl"
};
new szUpgradeModels[eLevelList][] = {
"models/csdm/dispenser1.mdl",
"models/csdm/dispenser2.mdl",
"models/csdm/dispenser3.mdl"
};
new szPlayerBoxModel[][] = {
"models/csdm/p_box_red.mdl",
"models/csdm/p_box_blue.mdl"
};
new szViewBoxModel[][] = {
"models/csdm/v_box_red.mdl",
"models/csdm/v_box_blue.mdl"
};
new g_CostUpgrade[3] = { 11, 12, 13 }; // Цена
new Float:g_Health[3] = { 100.0, 150.0, 200.0 }; // Hp
new Float:g_HealthRadius[3] = { 100.0, 150.0, 300.0 }; // Радиус действия
new Float:g_AddHealth[3] = { 5.0, 15.0, 25.0 }; // По сколько hp лечить
#define REFERENCE_WEAPON "weapon_ump45"
#define _ClassName "DispenserHP"
new gBeam;
public plugin_init()
{
register_plugin
(
"[AMXX] Health Dispenser",
_VERSION,
"Flymic24"
);
RegisterHam(Ham_TraceAttack, "info_target", "HamHook_Dispenser_TraceAttack", false);
RegisterHam(Ham_Killed, "info_target", "HamHook_Dispenser_Killed", false);
RegisterHookChain(RG_CBasePlayer_UseEmpty, "HamHook_Dispenser_Use", .post = true);
RegisterHookChain(RG_CBasePlayerWeapon_DefaultDeploy, "CBasePlayerWeapon_DefaultDeploy", false);
RegisterHookChain(RG_CBasePlayer_Spawn, "CBasePlayer_OnSpawnEquip", true);
RegisterHam(Ham_Item_PostFrame, REFERENCE_WEAPON, "HamHook_Item_PostFrame", false);
RegisterHam(Ham_Weapon_PrimaryAttack, REFERENCE_WEAPON, "HamHook_Item_PrimaryAttack", false);
RegisteFunc(REFERENCE_WEAPON);
AMMO_ID = rg_add_ammo_registry(WEAPON_LIST);
iKey = engfunc(EngFunc_AllocString, _ClassName);
}
public plugin_precache(){
precache_model(HealthSpr);
precache_sound(ActivateSound);
precache_model(PrintModel);
precache_model(GibsMdl);
for(new i = _Level1; i < eLevelList; i++){
precache_model(szDispenserModels[i]);
precache_model(szUpgradeModels[i]);
}
for(new i = 0; i < sizeof(szPlayerBoxModel); i++){
precache_model(szPlayerBoxModel[i]);
precache_model(szViewBoxModel[i]);
if(get_cvar_num("sv_auto_precache_sounds_in_models") == 0) {
PRECACHE_MODEL2(szViewBoxModel[i]);
}
}
gBeam = precache_model("sprites/csdm/tok.spr");
PRECACHE_WEAPONLIST(WEAPON_LIST);
}
/* *****************
Give custom dispenser
********************/
public CBasePlayer_OnSpawnEquip(const iPlayer){
if (EquipDelay > 0.0)
set_task(EquipDelay, "GiveEquip", iPlayer);
else
GiveEquip(iPlayer);
}
public GiveEquip(iPlayer) {
GiveObject(iPlayer, REFERENCE_WEAPON, iKey, AMMO_ID, MAX_DISPENCER);
}
public CBasePlayerWeapon_DefaultDeploy(const iItem, szViewModel[], szWeaponModel[], iAnim, szAnimExt[], skiplocal) {
if(!IsCustomItem(iItem))
return HC_CONTINUE;
new iPlayer;
if(!(iPlayer = get_member(iItem, m_pPlayer)) || !is_user_connected(iPlayer))
return HC_CONTINUE;
new iTeam = get_member(iPlayer, m_iTeam) - 1;
SetHookChainArg(2, ATYPE_STRING, szViewBoxModel[iTeam]);
SetHookChainArg(3, ATYPE_STRING, szPlayerBoxModel[iTeam]);
SetHookChainArg(4, ATYPE_INTEGER, _DRAW);
return HC_CONTINUE;
}
/*******************
Ham hook dispenser
********************/
public Default_Item_Holster(const iItem, const iPlayer) {
// Code
}
public Default_Item_AttachToPlayer(const iItem, const iPlayer) {
SetObjectWeaponList(iItem, iPlayer, AMMO_ID, WEAPON_LIST, MAX_DISPENCER, POSITION_NUM);
}
public HamHook_Item_PostFrame(const iItem){
if(!IsCustomItem(iItem))
return HAM_IGNORED;
new iPlayer;
if(!(iPlayer = get_member(iItem, m_pPlayer)) || !is_user_connected(iPlayer))
return HAM_IGNORED;
if(get_member(iPlayer, m_iAccount) >= g_CostUpgrade[_Level1] && get_member(iItem, m_Weapon_iDefaultAmmo) > 0) {
rg_add_account(iPlayer, g_CostUpgrade[_Level1]);
rg_add_account(iPlayer, -g_CostUpgrade[_Level1]);
}
new Float:vecSrc[eCoord], Float:vecAiming[eCoord];
GetPlantOrigin(iPlayer, vecSrc, vecAiming);
engfunc(EngFunc_TraceLine, vecSrc, vecAiming, IGNORE_MISSILE|IGNORE_GLASS|IGNORE_MONSTERS, iPlayer, 0);
new Float:flFraction; get_tr2(0, TR_flFraction, flFraction);
new iDispenser = iObjectID[iPlayer];
if (flFraction >= 1.0 || !is_user_alive(iPlayer)) {
if(!is_nullent(iDispenser)) {
UTIL_KillEntity(iDispenser);
}
iObjectID[iPlayer] = NULLENT;
return HAM_IGNORED;
}
else if(flFraction < 1.0) {
if(is_nullent(iDispenser)) {
iObjectID[iPlayer] = iDispenser = SpawnObject(_ClassName, PrintModel, Float:{-SIZE, -SIZE, 0.0}, Float:{SIZE, SIZE, 55.0});
}
new Float:fVecEnd[eCoord], Float:fVecNormal[eCoord], Float:fAngles[eCoord];
get_tr2(0, TR_vecEndPos, fVecEnd);
get_tr2(0, TR_vecPlaneNormal, fVecNormal);
xs_vec_mul_scalar(fVecNormal, 1.0, fVecNormal);
xs_vec_add(fVecEnd, fVecNormal, fVecEnd);
engfunc(EngFunc_SetOrigin, iDispenser, fVecEnd);
if (fVecNormal[2] == 1.0 && CheckLocation(iDispenser, fVecEnd, SIZE * 2)) {
set_entvar(iDispenser, var_sequence, _IDLE);
get_entvar(iPlayer, var_angles, fAngles);
fAngles[1] -= 180.0;
fAngles[0] += 12.0;
}
else {
set_entvar(iDispenser, var_sequence, _DRAW);
vector_to_angle(fVecNormal, fAngles);
fAngles[0] -= 90.0;
}
set_entvar(iDispenser, var_angles, fAngles);
}
return HAM_IGNORED;
}
public HamHook_Item_PrimaryAttack(const iItem){
if(!IsCustomItem(iItem))
return HAM_IGNORED;
new iPlayer;
if(!(iPlayer = get_member(iItem, m_pPlayer)) || !is_user_connected(iPlayer))
return HAM_IGNORED;
new iDispenser;
if (!(iDispenser = iObjectID[iPlayer]) || is_nullent(iDispenser))
return HAM_SUPERCEDE;
if (get_entvar(iDispenser, var_sequence) == _DRAW){
client_print(iPlayer, print_center, "Здесь строить нельзя");
return HAM_SUPERCEDE;
}
new iClip = get_member(iPlayer, m_rgAmmo, AMMO_ID);
if (--iClip < 0) {
client_print(iPlayer, print_center, "Более нельзя ставить");
return HAM_SUPERCEDE;
}
if(get_member(iPlayer, m_iAccount) < g_CostUpgrade[_Level1]) {
client_print(iPlayer, print_center, "Не достаточно средств: %i", g_CostUpgrade[_Level1]);
return HAM_SUPERCEDE;
}
set_member(iItem, m_Weapon_flNextPrimaryAttack, 1.0);
set_member(iItem, m_Weapon_iDefaultAmmo, iClip);
set_member(iPlayer, m_rgAmmo, iClip, AMMO_ID);
BuildObject(iPlayer, iDispenser, BUILD_TIME, ActivateSound, _IDLE, UPDATE_DELAY, szUpgradeModels[_Level1]);
rg_add_account(iPlayer, -g_CostUpgrade[_Level1]);
return HAM_SUPERCEDE;
}
/**********************************
Create dispenser and other effect
**********************************/
DispenserEffect(const iPlayer, Float:iAmmout){
if (get_entvar(iPlayer, var_health) >= MAX_HP && get_entvar(iPlayer, var_armorvalue) >= MAX_AP)
return false;
new iEnt = rg_create_entity("env_sprite");
if(is_nullent(iEnt))
return false;
new Float: fVecOrigin[eCoord]; get_entvar(iPlayer, var_origin, fVecOrigin); fVecOrigin[2] += 40.0;
engfunc(EngFunc_SetOrigin, iEnt, fVecOrigin);
engfunc(EngFunc_SetModel, iEnt, HealthSpr);
set_entvar(iEnt, var_solid, SOLID_NOT);
set_entvar(iEnt, var_movetype, MOVETYPE_FLY);
set_entvar(iEnt, var_scale, 0.2);
set_entvar(iEnt, var_velocity, {0.0, 0.0, 30.0});
set_entvar(iEnt, var_frame, iAmmout);
set_entvar(iEnt, var_nextthink, get_gametime() + 1.5);
SetThink(iEnt, "RemoveEntThink");
return true;
}
/**********************************
Brain to dispenser
**********************************/
#define UPDATE_TIME 0.05
public Object_Think(const iEntity) {
if (is_nullent(iEntity))
return;
new Float:fGameTime = get_gametime();
new iTeam = get_entvar(iEntity, var_team);
new iLevel = get_entvar(iEntity, object_level);
new iOwner = get_entvar(iEntity, object_owner);
if(!is_user_alive(iOwner) || get_member(iOwner, m_iTeam) != iTeam){
UTIL_KillEntity(iEntity);
return;
}
SetObjectInfoAim(fGameTime, iTeam, iEntity);
if (get_entvar(iEntity, object_active_time) > fGameTime) {
set_entvar(iEntity, var_nextthink, fGameTime + UPDATE_TIME);
return;
}
switch(get_entvar(iEntity, object_status)){
case _BUILDING: {
engfunc(EngFunc_SetModel, iEntity, szDispenserModels[iLevel]);
engfunc(EngFunc_SetSize, iEntity, Float:{-SIZE, -SIZE, 0.0}, Float:{SIZE, SIZE, 55.0});
set_entvar(iEntity, var_takedamage, DAMAGE_YES);
set_entvar(iEntity, var_health, g_Health[iLevel]);
set_entvar(iEntity, var_max_health, g_Health[iLevel]);
set_entvar(iEntity, object_status, _ACTIVE);
set_entvar(iEntity, object_active_time, fGameTime);
}
case _ACTIVE: {
new Float:fVecOrigin[eCoord]; get_entvar(iEntity, var_origin, fVecOrigin);
new iEnt = NULLENT;
while((iEnt = engfunc(EngFunc_FindEntityInSphere, iEnt, fVecOrigin, g_HealthRadius[iLevel])))
{
if (!UTIL_IsVisible(iEnt, iEntity)) continue;
if(is_user_alive(iEnt) && get_member(iEnt, m_iTeam) == iTeam) {
if (DispenserEffect(iEnt, g_AddHealth[iLevel])){
// ExecuteHamB(Ham_TakeHealth, iEnt, g_AddHealth[iLevel], DMG_GENERIC);
set_entvar(iEnt, var_health, floatmin(Float:get_entvar(iEnt, var_health) + g_AddHealth[iLevel], MAX_HP));
set_entvar(iEnt, var_armorvalue, floatmin(Float:get_entvar(iEnt, var_armorvalue) + g_AddHealth[iLevel], MAX_AP));
}
}
else if(IsActiveEnt(iEnt, iTeam)) {
set_entvar(iEnt, var_health, floatmin(Float:get_entvar(iEnt, var_health) + g_AddHealth[iLevel], Float:get_entvar(iEnt, var_max_health)));
UTIL_TE_BEAMENTS(iEnt, iEntity, gBeam);
}
}
set_entvar(iEntity, object_active_time, fGameTime + 2.0);
}
}
set_entvar(iEntity, var_nextthink, fGameTime + UPDATE_TIME);
}
public HamHook_Dispenser_Use(const pPlayer) {
new iEnt, iBody;
get_user_aiming(pPlayer, iEnt, iBody, floatround(PLANT_RADIUS));
if (!IsCustomObject(iEnt))
return;
if(get_member(pPlayer, m_iTeam) != get_entvar(iEnt, var_team))
return;
new iLevel = get_entvar(iEnt, object_level);
if (++iLevel >= eLevelList){
return;
}
UpgradeObject(pPlayer, iEnt, iLevel, _IDLE, UPGRADE_TIME, UPDATE_DELAY, g_CostUpgrade[iLevel], ActivateSound, szUpgradeModels[iLevel]);
}
public HamHook_Dispenser_Killed(const iVictim, const iAttacker){
if (is_nullent(iVictim))
return HAM_IGNORED;
if (!IsCustomObject(iVictim))
return HAM_IGNORED;
new Float:fVecOrigin[eCoord]; get_entvar(iVictim, var_origin, fVecOrigin);
UTIL_TE_EXPLOSION(fVecOrigin);
new iOwner = get_entvar(iVictim, object_owner);
if (is_user_connected(iOwner)) {
set_member(iOwner, m_rgAmmo, get_member(iOwner, m_rgAmmo, AMMO_ID) + 1, AMMO_ID);
}
CObject_Gibs(iVictim, GibsMdl, 3, get_entvar(iVictim, var_skin));
return HAM_IGNORED;
}
public HamHook_Dispenser_TraceAttack(iVictim, iAttacker, Float:flDamage, Float:flDirection[3], iTrace, iDamageBits){
if (!is_user_connected(iAttacker))
return HAM_IGNORED;
if (!IsCustomObject(iVictim))
return HAM_IGNORED;
if (get_entvar(iVictim, var_takedamage) != DAMAGE_YES)
return HAM_SUPERCEDE;
new Float:flEndOrigin[eCoord]; get_tr2(iTrace, TR_vecEndPos, flEndOrigin);
UTIL_TE_SPARKS(flEndOrigin);
if(get_entvar(iVictim, var_team) == get_member(iAttacker, m_iTeam) /*&& iAttacker != get_entvar(iVictim, object_owner)*/)
return HAM_SUPERCEDE;
rg_add_account(iAttacker, DMG_AWARD);
return HAM_IGNORED;
}
public ShowObjectInfoAim(const iPlayer, const iEnt, Float:fGameTime) {
new Float:iHealth = get_entvar(iEnt, var_health);
new iLevel = get_entvar(iEnt, object_level);
new iOwner = get_entvar(iEnt, object_owner);
new iTeam = get_entvar(iEnt, var_team);
set_dhudmessage(iTeam == _:TEAM_TERRORIST ? 120 : 0, 0, iTeam == _:TEAM_CT ? 255 : 0, -1.0, 0.35, 0, 0.0, 1.1, 0.0, 0.0);
show_dhudmessage(iPlayer, fmt("Владелец: %n^nПрочность: %i^nУровень: %i", iOwner, floatround(iHealth), iLevel + 1));
if (iLevel < eLevelList - 1) {
new Float:fUpdateTime; get_entvar(iEnt, object_update_time, fUpdateTime);
if (fGameTime < fUpdateTime)
show_dhudmessage(iPlayer, fmt("^n^n^nАпгрейд: %i$ Update: %i", g_CostUpgrade[iLevel + 1], floatround(fUpdateTime - fGameTime)));
else
show_dhudmessage(iPlayer, fmt("^n^n^nАпгрейд: %i$ Update: Нажмите на <E>", g_CostUpgrade[iLevel + 1]));
}
}
/*******************
Stock
********************/
bool: IsActiveEnt(const iEnt, const iTeam) {
if (is_nullent(iEnt))
return false;
if (get_entvar(iEnt, var_health) >= get_entvar(iEnt, var_max_health))
return false;
if (get_entvar(iEnt, var_team) != iTeam)
return false;
for(new a = 0; a < sizeof(szClassActive); a++) {
if (FClassnameIs(iEnt, szClassActive[a])) {
return true;
}
}
return false;
}
/*
Благодарность:
* KORD_12.7 - Beam entities include
*/
#include < amxmodx >
#include < csdm_object >
#include < beams >
#pragma semicolon 1
#define VERSION "1.0"
#define MAX_MINE_ONE_PLAYER 99 // Лимит
#define MINE_COST 1 // Цена
#define REWARD_DAMAGE random_num(1, 3)
#define REWARD_KILLED 400 // Награда разрушение
#define REWARD_OWNER 2 // Награда за убийсво миной
#define MINE_HEALTH 100.0 // Жизни
#define MINE_DAMAGE 10.0 // Урон
#define MINE_WIDTH 20.0 // Ширина луча
#define MINE_NOISE 10 // Искажение
#define SIZE_MINE 8.0 // Размер мины
enum _:eModels {
TripModel, PlayerModel, PrintModel, GibsMdl, SprT, SprCT
};
new szTripModel[eModels][MAX_RESOURCE_PATH_LENGTH] = {
"models/v_lasermine.mdl",
"models/p_lasermine.mdl",
"models/laser_blueprint.mdl",
"models/lasermine_gibs.mdl",
"sprites/laser_T.spr",
"sprites/laser_CT.spr"
};
enum _:eSounds{
Charge, Activate, Hit, HitEnemy
};
new szTripSound[eSounds][MAX_RESOURCE_PATH_LENGTH] = {
"weapons/mine_charge.wav",
"weapons/mine_activate.wav",
"weapons/sparks.wav",
"ambience/beamstart9.wav"
};
enum _:eAnimList {
Idle = 0, Idle2, Arm1, Place, fIdGet, Holster, Draw, World, Ground
};
new szClassActive[][16] = { // Классы обьектов
"Sentry", "DispenserHP", "_tripmine"
};
#define _ClassName "_tripmine"
#define PlantTime 1.0 // Через сколько можно ставить повторно
#define ActivationTime 2.0 // Время активации после установки
#define REFERENCE_WEAPON "weapon_mac10"
#define WEAPON_LIST "weapon_lasermine"
const POSITION_NUM = 1;
new HookChain:g_DeathNoticeHook;
public plugin_init()
{
register_plugin
(
"[AMXX] TripMine",
VERSION,
"Flymic24 (modified)"
);
RegisterHam(Ham_TraceAttack, "info_target", "HamHook_TripMine_TraceAttack", false);
RegisterHam(Ham_Killed, "info_target", "HamHook_TripMine_Killed", false);
RegisterHookChain(RG_CBasePlayerWeapon_DefaultDeploy, "CBasePlayerWeapon_DefaultDeploy", false);
DisableHookChain(g_DeathNoticeHook = RegisterHookChain(RG_CSGameRules_DeathNotice, "CSGameRules_DeathNotice", true));
RegisterHookChain(RG_CBasePlayer_Spawn, "CBasePlayer_OnSpawnEquip", true);
RegisterHam(Ham_Weapon_WeaponIdle, REFERENCE_WEAPON, "HamHook_Item_WeaponIdle", false);
RegisterHam(Ham_Item_PostFrame, REFERENCE_WEAPON, "HamHook_Item_PostFrame", false);
RegisterHam(Ham_Weapon_PrimaryAttack, REFERENCE_WEAPON, "HamHook_Item_PrimaryAttack", false);
register_message(get_user_msgid("DeathMsg"), "Msg_DeathMsg");
RegisteFunc(REFERENCE_WEAPON);
AMMO_ID = rg_add_ammo_registry(WEAPON_LIST);
iKey = engfunc(EngFunc_AllocString, _ClassName);
}
public plugin_precache(){
for(new a = 0; a < sizeof szTripSound; a++) precache_sound(szTripSound[a]);
for(new b = 0; b < sizeof szTripModel; b++) precache_model(szTripModel[b]);
if(get_cvar_num("sv_auto_precache_sounds_in_models") == 0) {
PRECACHE_MODEL2(szTripModel[TripModel]);
}
PRECACHE_WEAPONLIST(WEAPON_LIST);
}
/* *****************
Give custom dispenser
********************/
public CBasePlayer_OnSpawnEquip(const iPlayer){
if (EquipDelay > 0.0)
set_task(EquipDelay, "GiveEquip", iPlayer);
else
GiveEquip(iPlayer);
}
public GiveEquip(iPlayer) {
GiveObject(iPlayer, REFERENCE_WEAPON, iKey, AMMO_ID, MAX_MINE_ONE_PLAYER);
}
public CBasePlayerWeapon_DefaultDeploy(const iItem, szViewModel[], szWeaponModel[], iAnim, szAnimExt[], skiplocal) {
if(!IsCustomItem(iItem))
return HC_CONTINUE;
new iPlayer;
if(!(iPlayer = get_member(iItem, m_pPlayer)) || !is_user_connected(iPlayer))
return HC_CONTINUE;
SetHookChainArg(2, ATYPE_STRING, szTripModel[TripModel]);
SetHookChainArg(3, ATYPE_STRING, szTripModel[PlayerModel]);
SetHookChainArg(4, ATYPE_INTEGER, Draw);
return HC_CONTINUE;
}
/*******************
Ham hook TripMine
********************/
public Default_Item_Holster(const iItem, const iPlayer) {
// Code
}
public Default_Item_AttachToPlayer(const iItem, const iPlayer) {
SetObjectWeaponList(iItem, iPlayer, AMMO_ID, WEAPON_LIST, MAX_MINE_ONE_PLAYER, POSITION_NUM);
}
public HamHook_Item_WeaponIdle(const pItem) {
if(!IsCustomItem(pItem))
return HAM_IGNORED;
new iPlayer;
if(!(iPlayer = get_member(pItem, m_pPlayer)) || !is_user_connected(iPlayer))
return HAM_IGNORED;
if (get_member(pItem, m_Weapon_flTimeWeaponIdle) > 0.0)
return HAM_IGNORED;
switch(random_num(Idle, Idle2)) {
case Idle: {
set_member(pItem, m_Weapon_flTimeWeaponIdle, 3.0);
rg_weapon_send_animation(pItem, Idle);
}
case Idle2: {
set_member(pItem, m_Weapon_flTimeWeaponIdle, 2.0);
rg_weapon_send_animation(pItem, Idle2);
}
}
return HAM_SUPERCEDE;
}
public HamHook_Item_PostFrame(const iItem){
if(!IsCustomItem(iItem))
return HAM_IGNORED;
new iPlayer;
if(!(iPlayer = get_member(iItem, m_pPlayer)) || !is_user_connected(iPlayer))
return HAM_IGNORED;
if(get_member(iPlayer, m_iAccount) >= MINE_COST && get_member(iItem, m_Weapon_iDefaultAmmo) > 0) {
rg_add_account(iPlayer, MINE_COST);
rg_add_account(iPlayer, -MINE_COST);
}
new Float:vecSrc[eCoord], Float:vecAiming[eCoord];
GetPlantOrigin(iPlayer, vecSrc, vecAiming);
engfunc(EngFunc_TraceLine, vecSrc, vecAiming, IGNORE_MISSILE|IGNORE_GLASS|IGNORE_MONSTERS, iPlayer, 0);
new Float:flFraction; get_tr2(0, TR_flFraction, flFraction);
new iMine = iObjectID[iPlayer];
if (flFraction >= 1.0 || !is_user_alive(iPlayer)) {
if(!is_nullent(iMine)) {
UTIL_KillEntity(iMine);
}
iObjectID[iPlayer] = NULLENT;
return HAM_IGNORED;
}
else if(flFraction < 1.0) {
if(is_nullent(iMine)) {
iMine = iObjectID[iPlayer] = SpawnObject(_ClassName, szTripModel[PrintModel], Float:{-SIZE_MINE, -SIZE_MINE, -SIZE_MINE}, Float:{SIZE_MINE, SIZE_MINE, SIZE_MINE});
}
new Float:fVecEnd[eCoord], Float:fVecNormal[eCoord], Float:fAngles[eCoord];
get_tr2(0, TR_vecEndPos, fVecEnd);
get_tr2(0, TR_vecPlaneNormal, fVecNormal);
xs_vec_mul_scalar(fVecNormal, SIZE_MINE, fVecNormal);
xs_vec_add(fVecEnd, fVecNormal, fVecEnd);
engfunc(EngFunc_SetOrigin, iMine, fVecEnd);
vector_to_angle(fVecNormal, fAngles);
fAngles[0] -= 90.0;
set_entvar(iMine, var_angles, fAngles);
set_entvar(iMine, var_sequence, CheckLocation(iMine, fVecEnd, SIZE_MINE * 1.5, .fOfsetZ = 0.0, .bCheckDoor = false) ? Idle : Idle2);
}
return HAM_IGNORED;
}
public HamHook_Item_PrimaryAttack(const iItem){
if(!IsCustomItem(iItem))
return HAM_IGNORED;
new iPlayer;
if(!(iPlayer = get_member(iItem, m_pPlayer)) || !is_user_connected(iPlayer))
return HAM_IGNORED;
new iMine;
if (!(iMine = iObjectID[iPlayer]) || is_nullent(iMine))
return HAM_SUPERCEDE;
if (get_entvar(iMine, var_sequence) == Idle2){
client_print(iPlayer, print_center, "Здесь строить нельзя");
return HAM_SUPERCEDE;
}
new iClip = get_member(iPlayer, m_rgAmmo, AMMO_ID);
if (--iClip < 0) {
client_print(iPlayer, print_center, "Более нельзя ставить");
return HAM_SUPERCEDE;
}
if(get_member(iPlayer, m_iAccount) < MINE_COST) {
client_print(iPlayer, print_center, "Не достаточно средств: %i", MINE_COST);
return HAM_SUPERCEDE;
}
set_member(iItem, m_Weapon_flTimeWeaponIdle, 0.36);
set_member(iItem, m_Weapon_flNextPrimaryAttack, PlantTime);
set_member(iItem, m_Weapon_iDefaultAmmo, iClip);
set_member(iPlayer, m_rgAmmo, iClip, AMMO_ID);
rg_add_account(iPlayer, -MINE_COST);
rg_weapon_send_animation(iItem, Place);
Build_TripMine(iPlayer, iMine);
return HAM_SUPERCEDE;
}
/*******************
Kill Message
********************/
public CSGameRules_DeathNotice(const iVictim, const iAttacker, inflictor) {
rh_update_user_info(iAttacker);
DisableHookChain(g_DeathNoticeHook);
}
public Msg_DeathMsg() {
new szClassName[16]; get_msg_arg_string(4, szClassName, charsmax(szClassName));
if(!equali(szClassName, _ClassName))
return;
new iAttacker = get_msg_arg_int(1);
new szName[MAX_NAME_LENGTH]; get_user_name(iAttacker, szName, charsmax(szName));
EnableHookChain(g_DeathNoticeHook);
set_user_fake_name(iAttacker, fmt("%.14s [Lasermine]", szName));
set_msg_arg_string(4, "teammate");
}
public ShowObjectInfoAim(const iPlayer, const iEnt, Float:fGameTime) {
new Float:fHealth = get_entvar(iEnt, var_health);
new iKill = get_entvar(iEnt, object_data1);
new iOwner = get_entvar(iEnt, object_owner);
new iTeam = get_entvar(iEnt, var_team);
set_dhudmessage(iTeam == _:TEAM_TERRORIST ? 120 : 0, 0, iTeam == _:TEAM_CT ? 255 : 0, -1.0, 0.35, 0, 0.0, 1.1, 0.0, 0.0);
show_dhudmessage(iPlayer, fmt("Владелец: %n^nПрочность: %i^nУбийств: %i", iOwner, floatround(fHealth), iKill));
}
#define UPDATE_TIME 0.1
public Object_Think(const iMine) {
if (is_nullent(iMine))
return;
new iOwner = get_entvar(iMine, object_owner);
new iBeam = get_entvar(iMine, var_impulse);
new iTeam = get_entvar(iMine, var_team);
new Float:fGameTime = get_gametime();
if(!is_user_alive(iOwner) || get_member(iOwner, m_iTeam) != iTeam) {
if(!is_nullent(iBeam)) UTIL_KillEntity(iBeam);
UTIL_KillEntity(iMine);
return;
}
SetObjectInfoAim(fGameTime, iTeam, iMine);
if (get_entvar(iMine, object_active_time) > fGameTime) {
set_entvar(iMine, var_nextthink, fGameTime + UPDATE_TIME);
return;
}
new Float:fVecSrc[eCoord], Float:fVecEnd[eCoord];
switch(get_entvar(iMine, object_status)) {
case _BUILDING: {
new Float:m_vecDir[eCoord]; get_entvar(iMine, var_startpos, m_vecDir);
get_entvar(iMine, var_origin, fVecSrc);
xs_vec_copy(fVecSrc, fVecEnd);
xs_vec_mul_scalar(m_vecDir, SIZE_MINE, m_vecDir);
xs_vec_add(fVecSrc, m_vecDir, fVecSrc);
get_entvar(iMine, var_startpos, m_vecDir);
xs_vec_mul_scalar(m_vecDir, 32.0, m_vecDir);
xs_vec_add(fVecEnd, m_vecDir, fVecEnd);
engfunc(EngFunc_TraceLine, fVecSrc, fVecEnd, DONT_IGNORE_MONSTERS, iMine, 0);
new Float:flFraction; get_tr2(0, TR_flFraction, flFraction);
if(flFraction == 1.0)
{
new iPlayer = NULLENT;
while((iPlayer = engfunc(EngFunc_FindEntityInSphere, iPlayer, fVecSrc, SIZE_MINE * 1.5)))
{
if(is_user_alive(iPlayer)) {
set_entvar(iMine, var_nextthink, fGameTime + UPDATE_TIME);
return;
}
}
rh_emit_sound2(iMine, 0, CHAN_BODY, szTripSound[ Charge ], 0.0, ATTN_NORM, SND_STOP, 0);
rh_emit_sound2(iMine, 0, CHAN_ITEM, szTripSound[ Activate ]);
TripMine_MakeBeam(iMine);
set_entvar(iMine, var_solid, SOLID_BBOX);
set_entvar(iMine, var_renderfx, kRenderFxGlowShell);
set_entvar(iMine, var_rendermode, kRenderNormal);
set_entvar(iMine, var_takedamage, DAMAGE_YES);
set_entvar(iMine, var_health, MINE_HEALTH);
set_entvar(iMine, var_max_health, MINE_HEALTH);
set_entvar(iMine, var_renderamt, MINE_WIDTH);
set_entvar(iMine, object_status, _ACTIVE);
switch(iTeam)
{
case TEAM_TERRORIST: set_entvar(iMine, var_rendercolor, Float:{255.0, 0.0, 0.0} );
case TEAM_CT: set_entvar(iMine, var_rendercolor, Float:{0.0, 0.0, 255.0} );
}
}
set_entvar(iMine, var_nextthink, fGameTime + UPDATE_TIME);
return;
}
case _ACTIVE: {
if(is_nullent(iBeam)) {
set_entvar(iMine, var_nextthink, fGameTime + UPDATE_TIME);
return;
}
get_entvar(iMine, var_origin, fVecSrc);
get_entvar(iMine, var_endpos, fVecEnd);
new iTrace = create_tr2();
engfunc(EngFunc_TraceLine, fVecSrc, fVecEnd, DONT_IGNORE_MONSTERS, iMine, iTrace);
new pHit = get_tr2(iTrace, TR_pHit);
get_tr2(iTrace, TR_vecEndPos, fVecEnd);
Beam_SetStartPos(iBeam, fVecEnd);
Beam_SetNoise(iBeam, 0);
if (IsActiveEnt(pHit, iTeam)) {
if (get_entvar(pHit, var_takedamage) != DAMAGE_NO) {
ExecuteHamB(Ham_TakeDamage, pHit, iOwner, iOwner, MINE_DAMAGE, DMG_GENERIC);
UTIL_TE_SPARKS(fVecEnd);
}
}
else if (is_user_alive(pHit)) {
Beam_SetNoise(iBeam, MINE_NOISE);
UTIL_TE_SPARKS(fVecEnd);
if(get_member(pHit, m_iTeam) == iTeam)
{
rh_emit_sound2(pHit, pHit, CHAN_BODY, szTripSound[ Hit ]);
}
else
{
rh_emit_sound2(pHit, pHit, CHAN_BODY, szTripSound[ HitEnemy ]);
if (get_entvar(pHit, var_takedamage) != DAMAGE_NO)
ExecuteHamB(Ham_TakeDamage, pHit, iMine, iOwner, MINE_DAMAGE, DMG_GENERIC);
if (!is_user_alive(pHit))
{
rg_add_account(iOwner, REWARD_OWNER);
if (!is_nullent(iMine))
set_entvar(iMine, object_data1, get_entvar(iMine, object_data1) + 1);
}
}
}
free_tr2(iTrace);
}
}
set_entvar(iMine, var_nextthink, fGameTime + UPDATE_TIME);
}
public HamHook_TripMine_TraceAttack(iVictim, iAttacker, Float:flDamage, Float:flDir[3], iTrace, iDamageBits){
if(!is_user_connected(iAttacker))
return HAM_IGNORED;
if (!IsCustomObject(iVictim))
return HAM_IGNORED;
if (get_entvar(iVictim, var_takedamage) != DAMAGE_YES)
return HAM_SUPERCEDE;
new Float:flEndOrigin[eCoord]; get_tr2(iTrace, TR_vecEndPos, flEndOrigin);
UTIL_TE_SPARKS(flEndOrigin);
if(get_entvar(iVictim, var_team) == get_member(iAttacker, m_iTeam) /*&& iAttacker != get_entvar(iVictim, object_owner)*/)
return HAM_SUPERCEDE;
rg_add_account(iAttacker, REWARD_DAMAGE);
return HAM_IGNORED;
}
public HamHook_TripMine_Killed(const iMine, const iAttacker){
if (is_nullent(iMine))
return HAM_IGNORED;
if (!IsCustomObject(iMine))
return HAM_IGNORED;
new iBeam = get_entvar(iMine, var_impulse);
if(!is_nullent(iBeam)) UTIL_KillEntity(iBeam);
new Float:fVecOrigin[eCoord]; get_entvar(iMine, var_origin, fVecOrigin);
UTIL_TE_EXPLOSION(fVecOrigin);
new iOwner = get_entvar(iMine, object_owner);
new iTeam = get_entvar(iMine, var_team);
if (is_user_connected(iAttacker) && get_member(iAttacker, m_iTeam) != iTeam)
{
rg_add_account(iAttacker, REWARD_KILLED);
client_print_color(iOwner, print_team_default,"^3[^4Действие^3]^4 %n [laser destroyed]", iAttacker);
client_print_color(iAttacker, print_team_default, "^3[^4Действие^3]!y Вы взорвали мину. Ваша награда: ^3%i^4$!", REWARD_KILLED);
}
if (is_user_connected(iOwner)) {
set_member(iOwner, m_rgAmmo, get_member(iOwner, m_rgAmmo, AMMO_ID) + 1, AMMO_ID);
}
CObject_Gibs(iMine, szTripModel[GibsMdl], 3);
return HAM_IGNORED;
}
Build_TripMine(const iPlayer, const iEnt) {
if (!is_user_alive(iPlayer) || is_nullent(iEnt))
return;
new iTeam = get_member(iPlayer, m_iTeam);
new Float:fGameTime = get_gametime();
enum _:eData {
Max, Min
};
new Float:fSize[eData][eCoord];
get_entvar(iEnt, var_maxs, fSize[Max]); get_entvar(iEnt, var_mins, fSize[Min]);
engfunc(EngFunc_SetModel, iEnt, szTripModel[TripModel]);
engfunc(EngFunc_SetSize, iEnt, fSize[Min], fSize[Max]);
set_entvar(iEnt, var_team, iTeam);
set_entvar(iEnt, object_owner, iPlayer);
set_entvar(iEnt, object_status, _BUILDING);
set_entvar(iEnt, var_body, 3);
set_entvar(iEnt, var_rendermode, kRenderTransAdd);
set_entvar(iEnt, var_renderamt, 255.0);
UTIL_Animation(iEnt, World);
set_entvar(iEnt, var_nextthink, fGameTime);
set_entvar(iEnt, object_active_time, fGameTime + ActivationTime);
SetThink(iEnt, "Object_Think");
new Float:m_vecDir[eCoord]; get_entvar(iEnt, var_angles, m_vecDir); m_vecDir[0] += 90.0;
set_entvar(iEnt, var_angles, m_vecDir);
rh_emit_sound2(iEnt, 0, CHAN_BODY, szTripSound[ Charge ]);
engfunc(EngFunc_MakeVectors, m_vecDir);
get_global_vector(GL_v_forward, m_vecDir);
m_vecDir[2] = -m_vecDir[2];
set_entvar(iEnt, var_startpos, m_vecDir);
iObjectID[iPlayer] = NULLENT;
}
TripMine_MakeBeam(const iMine){
new iBeam = Beam_Create(get_entvar(iMine, var_team) == TEAM_TERRORIST ? szTripModel[SprT] : szTripModel[SprCT], MINE_WIDTH);
new Float:m_vecDir[eCoord], Float:fVecSrc[eCoord], Float:fVecOrigin[eCoord];
get_entvar(iMine, var_startpos, m_vecDir);
get_entvar(iMine, var_origin, fVecSrc);
xs_vec_copy(fVecSrc, fVecOrigin);
xs_vec_mul_scalar(m_vecDir, 8128.0, m_vecDir);
xs_vec_add(fVecSrc, m_vecDir, fVecSrc);
Beam_PointsInit(iBeam, fVecSrc, fVecOrigin);
Beam_SetScrollRate(iBeam, 255.0);
Beam_SetBrightness(iBeam, 255.0);
Beam_SetNoise(iBeam, 0);
set_entvar(iMine, var_impulse, iBeam);
set_entvar(iMine, var_endpos, fVecSrc);
}
bool: IsActiveEnt(const iEnt, const iTeam) {
if (is_nullent(iEnt))
return false;
if (get_entvar(iEnt, var_health) >= get_entvar(iEnt, var_max_health))
return false;
if (get_entvar(iEnt, var_team) != iTeam)
return false;
for(new a = 0; a < sizeof(szClassActive); a++) {
if (FClassnameIs(iEnt, szClassActive[a])) {
return true;
}
}
return false;
}