Veteran Member
Join Date: Jan 2015
Location: Cat
|
08-20-2016
, 15:48
Re: [L4D2] Improved Prevent M60 Drop
|
#2
|
You forgot to let me audit your code before you released it so i'v done it here.
Stuff i'v done:
Save Memory for vars that are not used much.
Optmized weapon detection
Saved handle for cvar instead of finding it all the time.
All the parts i touched are in my style of code
Made it look cleaner yay
Changed all edict checks to entity and GetEdict to GetEntity (Entities work will all stuff )
Not tested it so have at it, i have not coded in a while so im not confident in my code.
Code:
#include <sourcemod>
#include <sdktools>
#pragma semicolon 1
static bool:InReloadM60[MAXPLAYERS+1] = {false, ...};
static iLastWeapon[MAXPLAYERS+1];
static bool:bM60[MAXPLAYERS+1] = {false, ...};
static Handle:hAmmoCvarM60 = INVALID_HANDLE;//cache the handle
static iAmmoCvarM60 = -1;//save the value instead of getting the int everytime
// hind for static vs new, use static with recursive stuff like loops ect or you will be hording useless vars for ages untill its used again
// rewritten abit with love, well i hope it works im too lazy to test :p
public Plugin:myinfo =
{
name = "[L4D2] Perfected Prevent M60 Drop",
author = "MasterMind420, DeathChaos25, Ludastar",
description = "Prevents M60 from dropping and allows reloading, perfected by MasterMind420",
version = "1.1",
url = ""
}
public APLRes:AskPluginLoad2(Handle:myself, bool:late, String:error[], err_max)
{
decl String:sGameFolder[11];
GetGameFolderName(sGameFolder, sizeof(sGameFolder));
if (!StrEqual(sGameFolder, "left4dead2", false))
{
strcopy(error, err_max, "This plugin is for Left 4 Dead 2 Only!");
return APLRes_Failure;
}
return APLRes_Success;
}
public OnPluginStart()
{
HookEvent("receive_upgrade", Event_AmmoUpgrade);
HookEvent("upgrade_explosive_ammo", Event_AmmoUpgrade);
HookEvent("upgrade_incendiary_ammo", Event_AmmoUpgrade);
HookEvent("weapon_reload", Event_WeaponReloadPre, EventHookMode_Pre);
hAmmoCvarM60 = FindConVar("ammo_m60_max");//the handle we cache
HookConVarChange(hAmmoCvarM60, eConvarChanged);//hook the cvar change so the var will change
CreateTimer(0.1, M60AmmoCheck, _, TIMER_REPEAT);
}
public eConvarChanged(Handle:hCvar, const String:sOldVal[], const String:sNewVal[])
{
CvarsChanged();
}
CvarsChanged()
{
iAmmoCvarM60 = GetConVarInt(hAmmoCvarM60);
}
public Action:M60AmmoCheck(Handle:Timer)
{
if (!IsServerProcessing())
return Plugin_Continue;
static ReserveAmmo;
ReserveAmmo = iAmmoCvarM60;
for (new client = 1; client <= MaxClients; client++)// Make sure to use continue; not return; RETURN WILL EXIT THE WHOLE LOOP not skip to the next client in the loop
{
if(!IsSurvivor(client) || !IsPlayerAlive(client))
continue;
static Weapon;
Weapon = GetPlayerWeaponSlot(client, 0);
if(!IsValidEntity(Weapon))
continue;
if(iLastWeapon[client] != Weapon)// this little if statment is more perf friendly
{
iLastWeapon[client] = Weapon;
decl String:sWeapon[17];
GetEntityClassname(Weapon, sWeapon, sizeof(sWeapon));
if(sWeapon[13] != 'm' || !StrEqual(sWeapon, "weapon_rifle_m60"))
{
bM60[client] = false;
continue;
}
bM60[client] = true;
}
if(!bM60[client])
continue;
static Clip;
Clip = GetEntProp(Weapon, Prop_Data, "m_iClip1");
static PrimType;
PrimType = GetEntProp(Weapon, Prop_Send, "m_iPrimaryAmmoType");
static Ammo;
Ammo = GetEntProp(client, Prop_Send, "m_iAmmo", _, PrimType);
//static ReserveAmmo;
//ReserveAmmo = GetConVarInt(FindConVar("ammo_m60_max"));
//I already told you this already finding the handle everytime is pointless and wastes time finding ite every time, save the handle instead :P
if (Clip == 0 && Ammo ==0) { SetEntProp(Weapon, Prop_Send, "m_iClip1", 1); }
else if (Clip == 0 && Ammo > ReserveAmmo + 150) { SetEntProp(client, Prop_Send, "m_iAmmo", ReserveAmmo + 150, _, PrimType); }
else if (Clip > 0 && Ammo > ReserveAmmo) { SetEntProp(client, Prop_Send, "m_iAmmo", ReserveAmmo + (150 - Clip), _, PrimType); }
}
return Plugin_Continue;
}
public Action:Event_WeaponReloadPre(Handle:event, const String:name[], bool:dontBroadcast)
{
new client = GetClientOfUserId(GetEventInt(event, "userid"));
if(!IsSurvivor(client) || !IsPlayerAlive(client))
return Plugin_Continue;
new Weapon = GetEntPropEnt(client, Prop_Data, "m_hActiveWeapon");// use this the orignal method is deprecated so don't use it :P
if(!IsValidEntity(Weapon))
return Plugin_Continue;
if(iLastWeapon[client] != Weapon)// this little if statment is more perf friendly
{
iLastWeapon[client] = Weapon;
decl String:sWeapon[17];
GetEntityClassname(Weapon, sWeapon, sizeof(sWeapon));
if(sWeapon[13] != 'm' || !StrEqual(sWeapon, "weapon_rifle_m60"))
{
bM60[client] = false;
return Plugin_Continue;
}
bM60[client] = true;
}
if(!bM60[client])
return Plugin_Continue;
SetEntProp(Weapon, Prop_Send, "m_releasedFireButton", 1);
SetEntPropFloat(Weapon, Prop_Send, "m_flNextPrimaryAttack", GetGameTime() + 2.0); // + 1000.0);
return Plugin_Continue;
}
public Action:Event_AmmoUpgrade(Handle:event, const String:name[], bool:dontBroadcast)
{
new client = GetClientOfUserId(GetEventInt(event, "userid"));
if (!IsSurvivor(client) || !IsPlayerAlive(client))
return Plugin_Continue;
new Weapon = GetEntPropEnt(client, Prop_Data, "m_hActiveWeapon");
if(!IsValidEntity(Weapon))
return Plugin_Continue;
if(iLastWeapon[client] != Weapon)// this little if statment is more perf friendly
{
iLastWeapon[client] = Weapon;
decl String:sWeapon[17];
GetEntityClassname(Weapon, sWeapon, sizeof(sWeapon));
if(sWeapon[13] != 'm' || !StrEqual(sWeapon, "weapon_rifle_m60"))
{
bM60[client] = false;
return Plugin_Continue;
}
bM60[client] = true;
}
if(!bM60[client])
return Plugin_Continue;
new Clip = GetEntProp(Weapon, Prop_Data, "m_iClip1");
if (Clip != 0)
return Plugin_Continue;
new iAmmoCount = GetEntProp(iAmmoCount, Prop_Send, "m_iClip1");// Get ammo count because getting ammo on the m60 only give you the bullets that are in the clip with upgraded ammo that is standard l4d2 anyway :P.
SetEntProp(Weapon, Prop_Send, "m_nUpgradedPrimaryAmmoLoaded", iAmmoCount, 1);
SetEntProp(Weapon, Prop_Send, "m_iClip1", iAmmoCount);
return Plugin_Continue;
}
public Action:OnPlayerRunCmd(client, &buttons, &impulse, Float:vel[3], Float:angles[3])
{
if (!IsSurvivor(client) || !IsPlayerAlive(client))
return Plugin_Continue;
static Weapon;
Weapon = GetEntPropEnt(client, Prop_Data, "m_hActiveWeapon");
if(!IsValidEntity(Weapon))
return Plugin_Continue;
if(iLastWeapon[client] != Weapon)// this little if statment is more perf friendly
{
iLastWeapon[client] = Weapon;
decl String:sWeapon[17];
GetEntityClassname(Weapon, sWeapon, sizeof(sWeapon));
if(sWeapon[13] != 'm' || !StrEqual(sWeapon, "weapon_rifle_m60"))
{
bM60[client] = false;
return Plugin_Continue;
}
bM60[client] = true;
}
if(!bM60[client])
return Plugin_Continue;
static Clip;
Clip = GetEntProp(Weapon, Prop_Data, "m_iClip1");
static PrimType;
PrimType = GetEntProp(Weapon, Prop_Send, "m_iPrimaryAmmoType");
static Ammo;
Ammo = GetEntProp(client, Prop_Send, "m_iAmmo", _, PrimType);
static Laser;
Laser = GetEntProp(Weapon, Prop_Send, "m_upgradeBitVec");
static InReload;
InReload = GetEntProp(Weapon, Prop_Data, "m_bInReload");
if (Clip == 1) { InReloadM60[client]=true; }
if (buttons & IN_ATTACK && InReload) { return Plugin_Continue; }
if (buttons & IN_ATTACK && Clip <= 1 && InReloadM60[client])
{
AcceptEntityInput(Weapon, "kill");
new M60 = CreateEntityByName("weapon_rifle_m60");
DispatchSpawn(M60);
EquipPlayerWeapon(client, M60);
SetEntProp(M60, Prop_Send, "m_iClip1", 0);
SetEntProp(client, Prop_Send, "m_iAmmo", Ammo, _, PrimType);
SetEntProp(M60, Prop_Send, "m_upgradeBitVec", Laser);
InReloadM60[client]=false;
}
return Plugin_Continue;
}
static bool:IsSurvivor(client)
{
return client > 0 && client <= MaxClients && IsClientInGame(client) && GetClientTeam(client) == 2;
}
I could of put this in its own callback but was too lazy
Code:
if(iLastWeapon[client] != Weapon)// this little if statment is more perf friendly
{
iLastWeapon[client] = Weapon;
decl String:sWeapon[16];
GetEntityClassname(Weapon, sWeapon, sizeof(sWeapon));
if(sWeapon[13] != 'm' || !StrEqual(sWeapon, "weapon_rifle_m60"))
{
bM60[client] = false;
continue;
}
bM60[client] = true;
}
Edit 22/08/2016// Revision of 2 mistakes and now works
use 1.6 compiler because mastermind have issues with 1.7
__________________
Last edited by Lux; 09-03-2017 at 10:53.
Reason: Added more witches :D
|
|