Page 1 of 1

[ZP] Extra Item: Chainsaw v2

Posted: 19 Mar 2019, 22:56
by Rainq
Image
Descriere: Drujba pentru oameni.


Descarcare: LINK RESURSE!

Code: Select all

#include <amxmodx>
#include <fakemeta>
#include <hamsandwich>
#include <zombieplague>

#define CustomItem(%0) (pev(%0, pev_impulse) == WEAPON_SPECIAL_CODE)

enum _: e_AnimList
{
	WEAPON_ANIM_IDLE = 0,
	WEAPON_ANIM_DRAW,
	WEAPON_ANIM_DRAW_EMPTY,
	WEAPON_ANIM_ATTACK_START,
	WEAPON_ANIM_ATTACK_LOOP,
	WEAPON_ANIM_ATTACK_END,
	WEAPON_ANIM_RELOAD,
	WEAPON_ANIM_SLASH1,
	WEAPON_ANIM_SLASH2,
	WEAPON_ANIM_SLASH3,
	WEAPON_ANIM_SLASH4,
	WEAPON_ANIM_IDLE_EMPTY
};

enum _: e_HitResultList
{
	SLASH_HIT_NONE = 0,
	SLASH_HIT_WORLD,
	SLASH_HIT_ENTITY
};

enum _: e_AttackState
{
	STATE_NONE = 0,
	STATE_IN_LOOP,
	STATE_IN_END
};

// From model: Frames/FPS
#define WEAPON_ANIM_IDLE_TIME 151/30.0
#define WEAPON_ANIM_DRAW_TIME 46/30.0
#define WEAPON_ANIM_ATTACK_START_TIME 16/30.0
#define WEAPON_ANIM_ATTACK_LOOP_TIME 16/30.0
#define WEAPON_ANIM_ATTACK_END_TIME 46/30.0
#define WEAPON_ANIM_RELOAD_TIME 94/30.0
#define WEAPON_ANIM_SLASH_TIME 46/30.0

#define WEAPON_SPECIAL_CODE 3000
#define WEAPON_REFERENCE "weapon_m249"
#define WEAPON_NEW_NAME "x/weapon_chainsaw"

#define WEAPON_ITEM_NAME "Ripper (PowerSaw)"
#define WEAPON_ITEM_COST 200

#define WEAPON_MODEL_VIEW "models/x/v_chainsaw.mdl"
#define WEAPON_MODEL_PLAYER "models/x/p_chainsaw.mdl"
#define WEAPON_MODEL_WORLD "models/x/w_chainsaw.mdl"
#define WEAPON_BODY 0

#define WEAPON_SOUND_ATTACK_LOOP "weapons/chainsaw_attack1_loop.wav"
#define WEAPON_SOUND_ATTACK_HIT "weapons/chainsaw_hit1.wav"
#define WEAPON_SOUND_SLASH_HIT "weapons/chainsaw_hit2.wav"
#define WEAPON_SOUND_SLASH_HIT_EMPTY "weapons/chainsaw_hit3.wav"

#define WEAPON_MAX_CLIP 200
#define WEAPON_DEFAULT_AMMO 200
#define WEAPON_RATE 0.075

#define WEAPON_ANIM_EXTENSION_A "m249" // Original CSO: chainsaw (aim, reload, shoot)
#define WEAPON_ANIM_EXTENSION_B "knife" // Original CSO: chainsaw (shoot2)

#define WEAPON_ATTACK_DISTANCE 90.0
#define WEAPON_ATTACK_DAMAGE 50.0

#define WEAPON_SLASH_DISTANCE 140.0
#define WEAPON_SLASH_DAMAGE 200.0
#define WEAPON_SLASH_KNOCKBACK 500.0

new Float: flSendAnglesAttack[] = { 0.0 };
new Float: flSendAnglesUpAttack[] = { 0.0 };

new Float: flSendAnglesSlash[] = { 0.0, -10.0, 10.0, -20.0, 20.0 };
new Float: flSendAnglesUpSlash[] = { 0.0, 0.0, 0.0, 0.0, 0.0 };

new const iWeaponList[] = 
{ 
	3, 200,-1, -1, 0, 4, 20, 0 // weapon_m249
};

#define DONT_BLEED -1
#define ACT_RANGE_ATTACK1 28

// Linux extra offsets
#define linux_diff_animating 4
#define linux_diff_weapon 4
#define linux_diff_player 5

// CWeaponBox
#define m_rgpPlayerItems_CWeaponBox 34

// CBaseAnimating
#define m_flFrameRate 36
#define m_flGroundSpeed 37
#define m_flLastEventCheck 38
#define m_fSequenceFinished 39
#define m_fSequenceLoops 40

// CBasePlayerItem
#define m_pPlayer 41
#define m_pNext 42
#define m_iId 43

// CBasePlayerWeapon
#define m_flNextPrimaryAttack 46
#define m_flNextSecondaryAttack 47
#define m_flTimeWeaponIdle 48
#define m_iPrimaryAmmoType 49
#define m_iClip 51
#define m_fInReload 54
#define m_iWeaponState 74

// CBaseMonster
#define m_Activity 73
#define m_IdealActivity 74
#define m_LastHitGroup 75
#define m_flNextAttack 83

// CBasePlayer
#define m_flPainShock 108
#define m_iPlayerTeam 114
#define m_flLastAttackTime 220
#define m_rpgPlayerItems 367
#define m_pActiveItem 373
#define m_rgAmmo 376
#define m_szAnimExtention 492

new g_iszAllocString_Entity,
	g_iszAllocString_ModelView, 
	g_iszAllocString_ModelPlayer,

	g_iszModelIndexBloodSpray,
	g_iszModelIndexBloodDrop,

	g_iMsgID_Weaponlist,
	g_iItemID;

public plugin_init()
{
	register_plugin("[ZP] Weapon: Ripper (PowerSaw)", "1.0", "xUnicorn (t3rkecorejz) / Batcoh: Code base");

	g_iItemID = zp_register_extra_item(WEAPON_ITEM_NAME, WEAPON_ITEM_COST, ZP_TEAM_HUMAN);

	register_forward(FM_UpdateClientData,	"FM_Hook_UpdateClientData_Post", true);
	register_forward(FM_SetModel, 			"FM_Hook_SetModel_Pre", false);

	RegisterHam(Ham_Item_Holster,			WEAPON_REFERENCE,	"CWeapon__Holster_Post", true);
	RegisterHam(Ham_Item_Deploy,			WEAPON_REFERENCE,	"CWeapon__Deploy_Post", true);
	RegisterHam(Ham_Item_PostFrame,			WEAPON_REFERENCE,	"CWeapon__PostFrame_Pre", false);
	RegisterHam(Ham_Item_AddToPlayer,		WEAPON_REFERENCE,	"CWeapon__AddToPlayer_Post", true);
	RegisterHam(Ham_Weapon_Reload,			WEAPON_REFERENCE,	"CWeapon__Reload_Pre", false);
	RegisterHam(Ham_Weapon_WeaponIdle,		WEAPON_REFERENCE,	"CWeapon__WeaponIdle_Pre", false);
	RegisterHam(Ham_Weapon_PrimaryAttack,	WEAPON_REFERENCE,	"CWeapon__PrimaryAttack_Pre", false);
	RegisterHam(Ham_Weapon_SecondaryAttack,	WEAPON_REFERENCE,	"CWeapon__SecondaryAttack_Pre", false);

	g_iMsgID_Weaponlist = get_user_msgid("WeaponList");
}

public plugin_precache()
{
	// Hook weapon
	register_clcmd(WEAPON_NEW_NAME, "Command_HookWeapon");

	// Precache models
	engfunc(EngFunc_PrecacheModel, WEAPON_MODEL_VIEW);
	engfunc(EngFunc_PrecacheModel, WEAPON_MODEL_PLAYER);
	engfunc(EngFunc_PrecacheModel, WEAPON_MODEL_WORLD);

	// Precache generic
	UTIL_PrecacheSpritesFromTxt(WEAPON_NEW_NAME);
	
	// Precache sounds
	engfunc(EngFunc_PrecacheSound, WEAPON_SOUND_ATTACK_LOOP);
	engfunc(EngFunc_PrecacheSound, WEAPON_SOUND_ATTACK_HIT);
	engfunc(EngFunc_PrecacheSound, WEAPON_SOUND_SLASH_HIT);
	engfunc(EngFunc_PrecacheSound, WEAPON_SOUND_SLASH_HIT_EMPTY);

	UTIL_PrecacheSoundsFromModel(WEAPON_MODEL_VIEW);

	// Other
	g_iszAllocString_Entity = engfunc(EngFunc_AllocString, WEAPON_REFERENCE);
	g_iszAllocString_ModelView = engfunc(EngFunc_AllocString, WEAPON_MODEL_VIEW);
	g_iszAllocString_ModelPlayer = engfunc(EngFunc_AllocString, WEAPON_MODEL_PLAYER);

	// Model Index
	g_iszModelIndexBloodSpray = engfunc(EngFunc_PrecacheModel, "sprites/bloodspray.spr");
	g_iszModelIndexBloodDrop = engfunc(EngFunc_PrecacheModel, "sprites/blood.spr");
}

// [ Amxx ]
public zp_extra_item_selected(iPlayer, iItem)
{
	if(iItem == g_iItemID)
		Command_GiveWeapon(iPlayer);
}

public Command_HookWeapon(iPlayer)
{
	engclient_cmd(iPlayer, WEAPON_REFERENCE);
	return PLUGIN_HANDLED;
}

public Command_GiveWeapon(iPlayer)
{
	static iEntity; iEntity = engfunc(EngFunc_CreateNamedEntity, g_iszAllocString_Entity);
	if(iEntity <= 0) return 0;

	set_pev(iEntity, pev_impulse, WEAPON_SPECIAL_CODE);
	ExecuteHam(Ham_Spawn, iEntity);
	UTIL_DropWeapon(iPlayer, 1);

	if(!ExecuteHamB(Ham_AddPlayerItem, iPlayer, iEntity))
	{
		set_pev(iEntity, pev_flags, pev(iEntity, pev_flags) | FL_KILLME);
		return 0;
	}

	ExecuteHamB(Ham_Item_AttachToPlayer, iEntity, iPlayer);
	set_pdata_int(iEntity, m_iClip, WEAPON_MAX_CLIP, linux_diff_weapon);

	new iAmmoType = m_rgAmmo + get_pdata_int(iEntity, m_iPrimaryAmmoType, linux_diff_weapon);
	if(get_pdata_int(iPlayer, m_rgAmmo, linux_diff_player) < WEAPON_DEFAULT_AMMO)
	set_pdata_int(iPlayer, iAmmoType, WEAPON_DEFAULT_AMMO, linux_diff_player);

	emit_sound(iPlayer, CHAN_ITEM, "items/gunpickup2.wav", VOL_NORM, ATTN_NORM, 0, PITCH_NORM);
	return 1;
}

// [ Fakemeta ]
public FM_Hook_UpdateClientData_Post(iPlayer, SendWeapons, CD_Handle)
{
	if(get_cd(CD_Handle, CD_DeadFlag) != DEAD_NO) return;

	static iItem; iItem = get_pdata_cbase(iPlayer, m_pActiveItem, 5);
	if(iItem <= 0 || !CustomItem(iItem)) return;

	set_cd(CD_Handle, CD_flNextAttack, get_gametime() + 0.001);
}

public FM_Hook_SetModel_Pre(iEntity)
{
	static i, szClassName[32], iItem;
	pev(iEntity, pev_classname, szClassName, charsmax(szClassName));

	if(!equal(szClassName, "weaponbox")) return FMRES_IGNORED;

	for(i = 0; i < 6; i++)
	{
		iItem = get_pdata_cbase(iEntity, m_rgpPlayerItems_CWeaponBox + i, linux_diff_weapon);

		if(iItem > 0 && CustomItem(iItem))
		{
			engfunc(EngFunc_SetModel, iEntity, WEAPON_MODEL_WORLD);
			set_pev(iEntity, pev_body, WEAPON_BODY);
			
			return FMRES_SUPERCEDE;
		}
	}

	return FMRES_IGNORED;
}

// [ HamSandwich ]
public CWeapon__Holster_Post(iItem)
{
	if(!CustomItem(iItem)) return;
	static iPlayer; iPlayer = get_pdata_cbase(iItem, m_pPlayer, linux_diff_weapon);
	
	emit_sound(iPlayer, CHAN_ITEM, "common/null.wav", VOL_NORM, ATTN_NORM, 0, PITCH_NORM);
	set_pdata_int(iItem, m_iWeaponState, STATE_NONE, linux_diff_weapon);
}

public CWeapon__Deploy_Post(iItem)
{
	if(!CustomItem(iItem)) return;
	
	static iPlayer; iPlayer = get_pdata_cbase(iItem, m_pPlayer, linux_diff_weapon);

	set_pev_string(iPlayer, pev_viewmodel2, g_iszAllocString_ModelView);
	set_pev_string(iPlayer, pev_weaponmodel2, g_iszAllocString_ModelPlayer);

	UTIL_SendWeaponAnim(iPlayer, WEAPON_ANIM_DRAW);

	set_pdata_float(iPlayer, m_flNextAttack, WEAPON_ANIM_DRAW_TIME, linux_diff_player);
	set_pdata_float(iItem, m_flTimeWeaponIdle, WEAPON_ANIM_DRAW_TIME, linux_diff_weapon);
	set_pdata_string(iPlayer, m_szAnimExtention * 4, WEAPON_ANIM_EXTENSION_A, -1, linux_diff_player * linux_diff_animating);
}

public CWeapon__PostFrame_Pre(iItem)
{
	if(!CustomItem(iItem)) return HAM_IGNORED;

	static iPlayer; iPlayer = get_pdata_cbase(iItem, m_pPlayer, linux_diff_weapon);
	static iClip; iClip = get_pdata_int(iItem, m_iClip, linux_diff_weapon);
	static iButton; iButton = pev(iPlayer, pev_button);
	static iWeaponState; iWeaponState = get_pdata_int(iItem, m_iWeaponState, linux_diff_weapon);

	switch(iWeaponState)
	{
		case STATE_NONE:
		{
			if(get_pdata_int(iItem, m_fInReload, linux_diff_weapon) == 1)
			{
				static iAmmoType; iAmmoType = m_rgAmmo + get_pdata_int(iItem, m_iPrimaryAmmoType, linux_diff_weapon);
				static iAmmo; iAmmo = get_pdata_int(iPlayer, iAmmoType, linux_diff_player);
				static j; j = min(WEAPON_MAX_CLIP - iClip, iAmmo);

				set_pdata_int(iItem, m_iClip, iClip + j, linux_diff_weapon);
				set_pdata_int(iPlayer, iAmmoType, iAmmo - j, linux_diff_player);
				set_pdata_int(iItem, m_fInReload, 0, linux_diff_weapon);
			}

			if(iButton & IN_ATTACK2 && get_pdata_float(iItem, m_flNextSecondaryAttack, linux_diff_weapon) < 0.0)
			{
				ExecuteHamB(Ham_Weapon_SecondaryAttack, iItem);

				iButton &= ~IN_ATTACK2;
				set_pev(iPlayer, pev_button, iButton);
			}
		}
		case STATE_IN_LOOP:
		{
			if((pev(iPlayer, pev_weaponanim) == WEAPON_ANIM_ATTACK_START || pev(iPlayer, pev_weaponanim) == WEAPON_ANIM_ATTACK_LOOP) && !(iButton & IN_ATTACK) || !iClip)
			{
				set_pdata_int(iItem, m_iWeaponState, STATE_IN_END, linux_diff_weapon);
			}
		}
		case STATE_IN_END:
		{
			UTIL_SendWeaponAnim(iPlayer, WEAPON_ANIM_ATTACK_END);

			set_pdata_int(iItem, m_iWeaponState, STATE_NONE, linux_diff_weapon);
			set_pdata_float(iPlayer, m_flNextAttack, WEAPON_ANIM_ATTACK_END_TIME, linux_diff_player);
			set_pdata_float(iItem, m_flTimeWeaponIdle, WEAPON_ANIM_ATTACK_END_TIME, linux_diff_weapon);
		}
	}

	return HAM_IGNORED;
}

public CWeapon__AddToPlayer_Post(iItem, iPlayer)
{
	switch(pev(iItem, pev_impulse))
	{
		case WEAPON_SPECIAL_CODE: UTIL_WeaponList(iPlayer, true);
		case 0: UTIL_WeaponList(iPlayer, false);
	}
}

public CWeapon__Reload_Pre(iItem)
{
	if(!CustomItem(iItem)) return HAM_IGNORED;
	static iPlayer; iPlayer = get_pdata_cbase(iItem, m_pPlayer, linux_diff_weapon);

	static iClip; iClip = get_pdata_int(iItem, m_iClip, linux_diff_weapon);
	if(iClip >= WEAPON_MAX_CLIP) return HAM_SUPERCEDE;

	static iAmmoType; iAmmoType = m_rgAmmo + get_pdata_int(iItem, m_iPrimaryAmmoType, linux_diff_weapon);
	if(get_pdata_int(iPlayer, iAmmoType, linux_diff_player) <= 0) return HAM_SUPERCEDE

	set_pdata_int(iItem, m_iClip, 0, linux_diff_weapon);
	ExecuteHam(Ham_Weapon_Reload, iItem);
	set_pdata_int(iItem, m_iClip, iClip, linux_diff_weapon);
	set_pdata_int(iItem, m_fInReload, 1, linux_diff_weapon);

	if(get_pdata_int(iItem, m_iWeaponState, linux_diff_weapon) == STATE_IN_LOOP)
		set_pdata_int(iItem, m_iWeaponState, STATE_IN_END, linux_diff_weapon);

	UTIL_SendWeaponAnim(iPlayer, WEAPON_ANIM_RELOAD);

	static szAnimation[64];
	formatex(szAnimation, charsmax(szAnimation), pev(iPlayer, pev_flags) & FL_DUCKING ? "crouch_reload_%s" : "ref_reload_%s", WEAPON_ANIM_EXTENSION_A);
	UTIL_PlayerAnimation(iPlayer, szAnimation);

	set_pdata_float(iItem, m_flNextPrimaryAttack, WEAPON_ANIM_RELOAD_TIME, linux_diff_weapon);
	set_pdata_float(iItem, m_flNextSecondaryAttack, WEAPON_ANIM_RELOAD_TIME, linux_diff_weapon);
	set_pdata_float(iItem, m_flTimeWeaponIdle, WEAPON_ANIM_RELOAD_TIME, linux_diff_weapon);
	set_pdata_float(iPlayer, m_flNextAttack, WEAPON_ANIM_RELOAD_TIME, linux_diff_player);

	return HAM_SUPERCEDE;
}

public CWeapon__WeaponIdle_Pre(iItem)
{
	if(!CustomItem(iItem) || get_pdata_float(iItem, m_flTimeWeaponIdle, linux_diff_weapon) > 0.0) return HAM_IGNORED;
	static iPlayer; iPlayer = get_pdata_cbase(iItem, m_pPlayer, linux_diff_weapon);

	UTIL_SendWeaponAnim(iPlayer, WEAPON_ANIM_IDLE);
	set_pdata_float(iItem, m_flTimeWeaponIdle, WEAPON_ANIM_IDLE_TIME, linux_diff_weapon);

	return HAM_SUPERCEDE;
}

public CWeapon__PrimaryAttack_Pre(iItem)
{
	if(!CustomItem(iItem)) return HAM_IGNORED;
	static iPlayer; iPlayer = get_pdata_cbase(iItem, m_pPlayer, linux_diff_weapon);
	static iClip; iClip = get_pdata_int(iItem, m_iClip, linux_diff_weapon);
	static iWeaponState; iWeaponState = get_pdata_int(iItem, m_iWeaponState, linux_diff_weapon);
	static szAnimation[64];

	if(iClip == 0)
	{
		ExecuteHam(Ham_Weapon_PlayEmptySound, iItem);
		set_pdata_float(iItem, m_flNextPrimaryAttack, 0.2, linux_diff_weapon);

		return HAM_SUPERCEDE;
	}

	switch(iWeaponState)
	{
		case STATE_NONE:
		{
			UTIL_SendWeaponAnim(iPlayer, WEAPON_ANIM_ATTACK_START);

			set_pdata_int(iItem, m_iWeaponState, STATE_IN_LOOP, linux_diff_weapon);
			set_pdata_float(iItem, m_flNextPrimaryAttack, WEAPON_ANIM_ATTACK_START_TIME, linux_diff_weapon);
			set_pdata_float(iItem, m_flNextSecondaryAttack, WEAPON_ANIM_ATTACK_START_TIME, linux_diff_weapon);
			set_pdata_float(iItem, m_flTimeWeaponIdle, WEAPON_ANIM_ATTACK_START_TIME, linux_diff_weapon);
		}
		case STATE_IN_LOOP:
		{
			if(pev(iPlayer, pev_weaponanim) != WEAPON_ANIM_ATTACK_LOOP)
				UTIL_SendWeaponAnim(iPlayer, WEAPON_ANIM_ATTACK_LOOP);

			FakeTraceLine(iPlayer, iItem, 0, WEAPON_ATTACK_DISTANCE, WEAPON_ATTACK_DAMAGE, flSendAnglesAttack, flSendAnglesUpAttack, sizeof flSendAnglesAttack);

			formatex(szAnimation, charsmax(szAnimation), pev(iPlayer, pev_flags) & FL_DUCKING ? "crouch_shoot_%s" : "ref_shoot_%s", WEAPON_ANIM_EXTENSION_A);
			UTIL_PlayerAnimation(iPlayer, szAnimation);

			set_pdata_int(iItem, m_iClip, iClip - 1, linux_diff_weapon);
			set_pdata_float(iItem, m_flNextPrimaryAttack, WEAPON_RATE, linux_diff_weapon);
			set_pdata_float(iItem, m_flNextSecondaryAttack, WEAPON_ANIM_ATTACK_LOOP_TIME, linux_diff_weapon);
			set_pdata_float(iItem, m_flTimeWeaponIdle, WEAPON_ANIM_ATTACK_LOOP_TIME, linux_diff_weapon);
		}
	}

	return HAM_SUPERCEDE;
}

public CWeapon__SecondaryAttack_Pre(iItem)
{
	if(!CustomItem(iItem)) return HAM_IGNORED;
	static iPlayer; iPlayer = get_pdata_cbase(iItem, m_pPlayer, linux_diff_weapon);
	static iClip; iClip = get_pdata_int(iItem, m_iClip, linux_diff_weapon);
	static Float: vecPunchangle[3];
	static szAnimation[64];

	switch(iClip)
	{
		case 0: UTIL_SendWeaponAnim(iPlayer, random_num(WEAPON_ANIM_SLASH3, WEAPON_ANIM_SLASH4));
		default: UTIL_SendWeaponAnim(iPlayer, random_num(WEAPON_ANIM_SLASH1, WEAPON_ANIM_SLASH2));
	}

	vecPunchangle[0] = -5.0;
	vecPunchangle[1] = random_float(-2.5, 2.5);
	set_pev(iPlayer, pev_punchangle, vecPunchangle);

	FakeTraceLine(iPlayer, iItem, 1, WEAPON_SLASH_DISTANCE, WEAPON_SLASH_DAMAGE, flSendAnglesSlash, flSendAnglesUpSlash, sizeof flSendAnglesSlash);

	formatex(szAnimation, charsmax(szAnimation), pev(iPlayer, pev_flags) & FL_DUCKING ? "crouch_shoot_%s" : "ref_shoot_%s", WEAPON_ANIM_EXTENSION_B);
	UTIL_PlayerAnimation(iPlayer, szAnimation);

	set_pdata_float(iItem, m_flNextPrimaryAttack, WEAPON_ANIM_SLASH_TIME - 0.3, linux_diff_weapon);
	set_pdata_float(iItem, m_flNextSecondaryAttack, WEAPON_ANIM_SLASH_TIME - 0.3, linux_diff_weapon);
	set_pdata_float(iItem, m_flTimeWeaponIdle, WEAPON_ANIM_SLASH_TIME - 0.3, linux_diff_weapon);

	return HAM_SUPERCEDE;
}

// [ Stocks ]
public FakeTraceLine(iPlayer, iItem, iSlash, Float: flDistance, Float: flDamage, Float:flSendAngles[], Float:flSendAnglesUp[], iSendAngles)
{
	new Float: flOrigin[3], Float: flAngle[3], Float: flEnd[3], Float: flViewOfs[3];
	new Float: flForw[3], Float: flUp[3], Float: flRight[3];

	pev(iPlayer, pev_origin, flOrigin);
	pev(iPlayer, pev_view_ofs, flViewOfs);

	flOrigin[0] += flViewOfs[0];
	flOrigin[1] += flViewOfs[1];
	flOrigin[2] += flViewOfs[2];
			
	pev(iPlayer, pev_v_angle, flAngle);
	engfunc(EngFunc_AngleVectors, flAngle, flForw, flRight, flUp);

	new iTrace = create_tr2();

	new Float: flTan;
	new Float: flMul;

	static Float: flFraction, pHit;
	static pHitEntity; pHitEntity = SLASH_HIT_NONE;
	static iHitResult; iHitResult = SLASH_HIT_NONE;

	for(new i; i < iSendAngles; i++)
	{
		flTan = floattan(flSendAngles[i], degrees);

		flEnd[0] = (flForw[0] * flDistance) + (flRight[0] * flTan * flDistance) + flUp[0] * flSendAnglesUp[i];
		flEnd[1] = (flForw[1] * flDistance) + (flRight[1] * flTan * flDistance) + flUp[1] * flSendAnglesUp[i];
		flEnd[2] = (flForw[2] * flDistance) + (flRight[2] * flTan * flDistance) + flUp[2] * flSendAnglesUp[i];
			
		flMul = (flDistance/vector_length(flEnd));
		flEnd[0] *= flMul;
		flEnd[1] *= flMul;
		flEnd[2] *= flMul;

		flEnd[0] = flEnd[0] + flOrigin[0];
		flEnd[1] = flEnd[1] + flOrigin[1];
		flEnd[2] = flEnd[2] + flOrigin[2];

		engfunc(EngFunc_TraceLine, flOrigin, flEnd, DONT_IGNORE_MONSTERS, iPlayer, iTrace);
		get_tr2(iTrace, TR_flFraction, flFraction);

		if(flFraction == 1.0)
		{
			engfunc(EngFunc_TraceHull, flOrigin, flEnd, HULL_HEAD, iPlayer, iTrace);
			get_tr2(iTrace, TR_flFraction, flFraction);
		
			engfunc(EngFunc_TraceLine, flOrigin, flEnd, DONT_IGNORE_MONSTERS, iPlayer, iTrace);
			pHit = get_tr2(iTrace, TR_pHit);
		}
		else
		{
			pHit = get_tr2(iTrace, TR_pHit);
		}

		if(flFraction != 1.0)
		{
			if(!iHitResult) iHitResult = SLASH_HIT_WORLD;
		}

		if(pHit > 0 && pHitEntity != pHit)
		{
			if(pev(pHit, pev_solid) == SOLID_BSP && !(pev(pHit, pev_spawnflags) & SF_BREAK_TRIGGER_ONLY))
			{
				ExecuteHamB(Ham_TakeDamage, pHit, iPlayer, iPlayer, flDamage, DMG_NEVERGIB | DMG_CLUB);
			}
			else
			{
				FakeTraceAttack(pHit, iPlayer, flDamage, flForw, iTrace, DMG_NEVERGIB | DMG_CLUB);
				if(iSlash) FakeKnockBack(pHit, flForw, WEAPON_SLASH_KNOCKBACK);
			}

			iHitResult = SLASH_HIT_ENTITY;
			pHitEntity = pHit;
		}
	}

	free_tr2(iTrace);

	static iClip; iClip = get_pdata_int(iItem, m_iClip, linux_diff_weapon);

	switch(iHitResult)
	{
		case SLASH_HIT_NONE:
		{
			if(!iSlash) emit_sound(iPlayer, CHAN_ITEM, WEAPON_SOUND_ATTACK_LOOP, VOL_NORM, ATTN_NORM, 0, PITCH_NORM);
		}
		case SLASH_HIT_WORLD, SLASH_HIT_ENTITY:
		{
			if(iSlash)
			{
				if(iClip) emit_sound(iPlayer, CHAN_WEAPON, WEAPON_SOUND_SLASH_HIT, VOL_NORM, ATTN_NORM, 0, PITCH_NORM);
				else emit_sound(iPlayer, CHAN_WEAPON, WEAPON_SOUND_SLASH_HIT_EMPTY, VOL_NORM, ATTN_NORM, 0, PITCH_NORM);
			}
			else
			{
				static Float: vecPunchangle[3];
				vecPunchangle[0] = random_float(-1.7, 1.7);
				vecPunchangle[1] = random_float(-1.7, 1.7);
				set_pev(iPlayer, pev_punchangle, vecPunchangle);

				emit_sound(iPlayer, CHAN_WEAPON, WEAPON_SOUND_ATTACK_HIT, VOL_NORM, ATTN_NORM, 0, PITCH_NORM);
			}
		}
	}
}

public FakeTraceAttack(iVictim, iAttacker, Float: flDamage, Float: vecDirection[3], iTrace, ibitsDamageBits)
{
	static Float: flTakeDamage; pev(iVictim, pev_takedamage, flTakeDamage);

	if(flTakeDamage == DAMAGE_NO) return 0; 
	if(!(is_user_alive(iVictim))) return 0;

	if(is_user_connected(iVictim)) 
	{
		if(get_pdata_int(iVictim, m_iPlayerTeam, linux_diff_player) == get_pdata_int(iAttacker, m_iPlayerTeam, linux_diff_player)) 
			return 0;
	}

	static iHitgroup; iHitgroup = get_tr2(iTrace, TR_iHitgroup);
	static Float: vecEndPos[3]; get_tr2(iTrace, TR_vecEndPos, vecEndPos);
	static iBloodColor; iBloodColor = ExecuteHamB(Ham_BloodColor, iVictim);
	
	set_pdata_int(iVictim, m_LastHitGroup, iHitgroup, linux_diff_player);

	switch(iHitgroup) 
	{
		case HIT_HEAD:                  flDamage *= 3.0;
		case HIT_LEFTARM, HIT_RIGHTARM: flDamage *= 0.75;
		case HIT_LEFTLEG, HIT_RIGHTLEG: flDamage *= 0.75;
		case HIT_STOMACH:               flDamage *= 1.5;
	}
	
	ExecuteHamB(Ham_TakeDamage, iVictim, iAttacker, iAttacker, flDamage, ibitsDamageBits);
	
	if(zp_get_user_zombie(iVictim)) 
	{
		if(iBloodColor != DONT_BLEED) 
		{
			ExecuteHamB(Ham_TraceBleed, iVictim, flDamage, vecDirection, iTrace, ibitsDamageBits);
			UTIL_BloodDrips(vecEndPos, iBloodColor, floatround(flDamage));
		}
	}

	return 1;
}

public FakeKnockBack(iVictim, Float: vecDirection[3], Float: flKnockBack) 
{
	if(!(is_user_alive(iVictim) && zp_get_user_zombie(iVictim))) return 0;

	set_pdata_float(iVictim, m_flPainShock, 1.0, linux_diff_player);

	static Float:vecVelocity[3]; pev(iVictim, pev_velocity, vecVelocity);

	if(pev(iVictim, pev_flags) & FL_DUCKING) 
		flKnockBack *= 0.7;

	vecVelocity[0] = vecDirection[0] * flKnockBack;
	vecVelocity[1] = vecDirection[1] * flKnockBack;
	vecVelocity[2] = 200.0;

	set_pev(iVictim, pev_velocity, vecVelocity);
	
	return 1;
}

public UTIL_BloodDrips(Float:vecOrigin[3], iColor, iAmount)
{
	if(iAmount > 255) iAmount = 255;
	
	engfunc(EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, vecOrigin, 0);
	write_byte(TE_BLOODSPRITE);
	engfunc(EngFunc_WriteCoord, vecOrigin[0]);
	engfunc(EngFunc_WriteCoord, vecOrigin[1]);
	engfunc(EngFunc_WriteCoord, vecOrigin[2]);
	write_short(g_iszModelIndexBloodSpray);
	write_short(g_iszModelIndexBloodDrop);
	write_byte(iColor);
	write_byte(min(max(3,iAmount/10),16));
	message_end();
}

stock UTIL_SendWeaponAnim(iPlayer, iAnim)
{
	set_pev(iPlayer, pev_weaponanim, iAnim);

	message_begin(MSG_ONE, SVC_WEAPONANIM, _, iPlayer);
	write_byte(iAnim);
	write_byte(0);
	message_end();
}

stock UTIL_DropWeapon(iPlayer, iSlot)
{
	static iEntity, iNext, szWeaponName[32];
	iEntity = get_pdata_cbase(iPlayer, m_rpgPlayerItems + iSlot, linux_diff_player);

	if(iEntity > 0)
	{       
		do 
		{
			iNext = get_pdata_cbase(iEntity, m_pNext, linux_diff_weapon);

			if(get_weaponname(get_pdata_int(iEntity, m_iId, linux_diff_weapon), szWeaponName, charsmax(szWeaponName)))
				engclient_cmd(iPlayer, "drop", szWeaponName);
		} 
		
		while((iEntity = iNext) > 0);
	}
}

stock UTIL_PrecacheSoundsFromModel(const szModelPath[])
{
	new iFile;
	
	if((iFile = fopen(szModelPath, "rt")))
	{
		new szSoundPath[64];
		
		new iNumSeq, iSeqIndex;
		new iEvent, iNumEvents, iEventIndex;
		
		fseek(iFile, 164, SEEK_SET);
		fread(iFile, iNumSeq, BLOCK_INT);
		fread(iFile, iSeqIndex, BLOCK_INT);
		
		for(new k, i = 0; i < iNumSeq; i++)
		{
			fseek(iFile, iSeqIndex + 48 + 176 * i, SEEK_SET);
			fread(iFile, iNumEvents, BLOCK_INT);
			fread(iFile, iEventIndex, BLOCK_INT);
			fseek(iFile, iEventIndex + 176 * i, SEEK_SET);
			
			for(k = 0; k < iNumEvents; k++)
			{
				fseek(iFile, iEventIndex + 4 + 76 * k, SEEK_SET);
				fread(iFile, iEvent, BLOCK_INT);
				fseek(iFile, 4, SEEK_CUR);
				
				if(iEvent != 5004)
					continue;
				
				fread_blocks(iFile, szSoundPath, 64, BLOCK_CHAR);
				
				if(strlen(szSoundPath))
				{
					strtolower(szSoundPath);
					engfunc(EngFunc_PrecacheSound, szSoundPath);
				}
			}
		}
	}
	
	fclose(iFile);
}

stock UTIL_PrecacheSpritesFromTxt(const szWeaponList[])
{
	new szTxtDir[64], szSprDir[64]; 
	new szFileData[128], szSprName[48], temp[1];

	format(szTxtDir, charsmax(szTxtDir), "sprites/%s.txt", szWeaponList);
	engfunc(EngFunc_PrecacheGeneric, szTxtDir);

	new iFile = fopen(szTxtDir, "rb");
	while(iFile && !feof(iFile)) 
	{
		fgets(iFile, szFileData, charsmax(szFileData));
		trim(szFileData);

		if(!strlen(szFileData)) 
			continue;

		new pos = containi(szFileData, "640");	
			
		if(pos == -1)
			continue;
			
		format(szFileData, charsmax(szFileData), "%s", szFileData[pos+3]);		
		trim(szFileData);

		strtok(szFileData, szSprName, charsmax(szSprName), temp, charsmax(temp), ' ', 1);
		trim(szSprName);
		
		format(szSprDir, charsmax(szSprDir), "sprites/%s.spr", szSprName);
		engfunc(EngFunc_PrecacheGeneric, szSprDir);
	}

	if(iFile) fclose(iFile);
}

stock UTIL_WeaponList(iPlayer, bool: bEnabled)
{
	message_begin(MSG_ONE, g_iMsgID_Weaponlist, _, iPlayer);
	write_string(bEnabled ? WEAPON_NEW_NAME : WEAPON_REFERENCE);
	write_byte(iWeaponList[0]);
	write_byte(bEnabled ? WEAPON_DEFAULT_AMMO : iWeaponList[1]);
	write_byte(iWeaponList[2]);
	write_byte(iWeaponList[3]);
	write_byte(iWeaponList[4]);
	write_byte(iWeaponList[5]);
	write_byte(iWeaponList[6]);
	write_byte(iWeaponList[7]);
	message_end();
}

stock UTIL_PlayerAnimation(const iPlayer, const szAnim[])
{
	new iAnimDesired, Float: flFrameRate, Float: flGroundSpeed, bool: bLoops;
		
	if((iAnimDesired = lookup_sequence(iPlayer, szAnim, flFrameRate, bLoops, flGroundSpeed)) == -1)
	{
		iAnimDesired = 0;
	}
	
	new Float: flGameTime = get_gametime();

	set_pev(iPlayer, pev_frame, 0.0);
	set_pev(iPlayer, pev_framerate, 1.0);
	set_pev(iPlayer, pev_animtime, flGameTime);
	set_pev(iPlayer, pev_sequence, iAnimDesired);
	
	set_pdata_int(iPlayer, m_fSequenceLoops, bLoops, linux_diff_animating);
	set_pdata_int(iPlayer, m_fSequenceFinished, 0, linux_diff_animating);
	
	set_pdata_float(iPlayer, m_flFrameRate, flFrameRate, linux_diff_animating);
	set_pdata_float(iPlayer, m_flGroundSpeed, flGroundSpeed, linux_diff_animating);
	set_pdata_float(iPlayer, m_flLastEventCheck, flGameTime , linux_diff_animating);
	
	set_pdata_int(iPlayer, m_Activity, ACT_RANGE_ATTACK1, linux_diff_player);
	set_pdata_int(iPlayer, m_IdealActivity, ACT_RANGE_ATTACK1, linux_diff_player);
	set_pdata_float(iPlayer, m_flLastAttackTime, flGameTime , linux_diff_player);
}
Nume: [ZP] Extra Item: Chainsaw v2
Versiune: -
Link oficial: -


Instalare:
1. Fisierul zp_weapon_chainsaw.sma il puneti in addons/amxmodx/scripting
2. Fisierul zp_weapon_chainsaw.amxx il puneti in addons/amxmodx/plugins
3. Intrati in fisierul addons/amxmodx/configs/plugins-zplague.ini si adaugati la urma:

Code: Select all

zp_weapon_chainsaw.amxx
4. Alti pasi necesari....

Cvar-uri (se adauga in fisierul amxmodx\configs\amxx.cfg): -



Imagini: Image