Untested, but this is how I would write it.
I would test it, but we do not have any CSS server going at this time.
When you write code, try not to use any timers unless you have to!
This code is setup so that the mine entity is attached to the owner. If the entity is greater than -1 is then it was created.
There is a spot where you seem to be checking to see if the enemy is not equal to this race, which i am guessing if you are this race.. your immune to the tripmines? This would cause a issue, if your test subjects are this race. I left it in, because it seems that is what you want.
if(War3_GetRace(enemy)!=thisRaceID)
Wish you would tell us what version of sourcemod your compiling this for, cause I would have updated the code for 1.7 sourcemod. The version you was writing in was version 1.6 or less.
#pragma semicolon 1
#include <sourcemod>
#include "W3SIncs/War3Source_Interface"
#define myLoopMaxClients(%1) for(new %1=1;%1<=MaxClients;++%1)
#define myLoopAlivePlayers(%1) for(new %1=1;%1<=MaxClients;++%1)\
if(IsClientInGame(%1) && IsPlayerAlive(%1))
new thisRaceID;
new SKILL_MINE;
// Mine
new String:MineModel[]="models/props_lab/tpplug.mdl";
new iMineOwner[MAXPLAYERS] = {-1, ...};
new Float:TripMineCD[]={0.0,60.0,50.0,40.0,30.0};
new Float:MineRange[]={0.0,150.0,175.0,200.0,250.0};
new Float:TripMineDuration[]={0.0,15.0,20.0,25.0,30.0};
new BeamSprite,HaloSprite,g_iExplosionModel,g_iSmokeModel;
new MineDamage[]={0,10,20,30,40};
new String:warningsnd[]="npc/roller/remote_yes.wav";
new String:explodesnd[]="weapons/explode5.wav";
#define TRACE_START 24.0
#define TRACE_END 64.0
public OnWar3PluginReady()
{
thisRaceID=War3_CreateNewRace("TripMine","Tripmine");
SKILL_MINE=War3_AddRaceSkill(thisRaceID, "Tripmine", "Plant a tripmine that enemies can trigger to blow up (+ability1)", false, 4 );
War3_CreateRaceEnd(thisRaceID);
}
public OnMapStart()
{
PrecacheModel(MineModel);
BeamSprite=PrecacheModel("materials/sprites/lgtning.vmt");
HaloSprite=PrecacheModel("materials/sprites/halo01.vmt");
g_iExplosionModel = PrecacheModel("materials/effects/fire_cloud1.vmt");
g_iSmokeModel = PrecacheModel("materials/effects/fire_cloud2.vmt");
War3_PrecacheSound(warningsnd);
War3_PrecacheSound(explodesnd);
myLoopMaxClients(client)
{
InitPassiveSkills(client);
}
}
public OnWar3EventSpawn(client)
{
if( War3_GetRace(client) == thisRaceID )
{
InitPassiveSkills(client);
}
}
public OnRaceChanged(client,oldrace,newrace)
{
if(newrace==thisRaceID)
{
InitPassiveSkills(client);
}
else if(oldrace==thisRaceID)
{
RemovePassiveSkills(client);
}
/*
if( newrace != thisRaceID )
{
War3_WeaponRestrictTo( client, thisRaceID, "" );
W3ResetAllBuffRace( client, thisRaceID );
}
else
{
iMineOwner[client]=-1;
}
*/
}
public InitPassiveSkills(client)
{
iMineOwner[client]=-1;
}
public RemovePassiveSkills(client)
{
KillMine(client);
iMineOwner[client]=-1;
War3_WeaponRestrictTo( client, thisRaceID, "" );
W3ResetAllBuffRace( client, thisRaceID );
}
public OnWar3Event(W3EVENT:event,client)
{
if(event == InitPlayerVariables) // client put in server
{
InitPassiveSkills(client);
}
else if(event == ClearPlayerVariables) // ondisconnect
{
RemovePassiveSkills(client);
}
}
/* *************************************** TripMine *************************************** */
public bool:CreateMine(client)
{
if(ValidPlayer(client))
{
new bool:MineCreated = false;
decl Float:start[3], Float:angle[3], Float:end[3], Float:normal[3];
GetClientEyePosition(client,start);
GetClientEyeAngles(client,angle);
GetAngleVectors(angle, end, NULL_VECTOR, NULL_VECTOR);
NormalizeVector(end, end);
start[0]=start[0]+end[0]*TRACE_START;
start[1]=start[1]+end[1]*TRACE_START;
start[2]=start[2]+end[2]*TRACE_START;
end[0]=start[0]+end[0]*TRACE_END;
end[1]=start[1]+end[1]*TRACE_END;
end[2]=start[2]+end[2]*TRACE_END;
TR_TraceRayFilter(start, end, CONTENTS_SOLID, RayType_EndPoint, FilterAll, 0);
if (TR_DidHit(INVALID_HANDLE))
{
TR_GetEndPosition(end, INVALID_HANDLE);
TR_GetPlaneNormal(INVALID_HANDLE, normal);
GetVectorAngles(normal, normal);
new mine = CreateEntityByName("prop_physics_override");
if(mine > -1)
{
SetEntityModel(mine, MineModel);
DispatchKeyValue(mine, "StartDisabled", "false");
DispatchSpawn(mine);
TeleportEntity(mine, end, normal, NULL_VECTOR);
SetEntProp(mine, Prop_Data, "m_usSolidFlags", 152);
SetEntProp(mine, Prop_Data, "m_CollisionGroup", 1);
SetEntityMoveType(mine, MOVETYPE_NONE);
SetEntProp(mine, Prop_Data, "m_MoveCollide", 0);
SetEntProp(mine, Prop_Data, "m_nSolidType", 6);
SetEntPropEnt(mine, Prop_Data, "m_hLastAttacker", client);
AcceptEntityInput(mine, "Enable");
iMineOwner[client]=mine;
MineCreated=true;
}
}
}
return MineCreated;
}
public OnAbilityCommand(client,ability,bool:pressed)
{
if(ValidPlayer(client,true) && War3_GetRace(client)==thisRaceID && pressed)
{
if(!Silenced(client))
{
if(ability==0)
{
// print Text If Not Ready = true
if(War3_SkillNotInCooldown(client,thisRaceID,SKILL_MINE,true))
{
if(War3_GetSkillLevel(client,thisRaceID,SKILL_MINE) > 0)
{
if (iMineOwner[client] > -1)
{
if(CreateMine(client))
{
PrintHintText(client, "Tripmine is planted!");
}
else
{
PrintHintText(client, "Tripmine planting unsuccessful!");
}
}
else
{
PrintHintText(client, "You already have a Tripmine planted");
}
}
else
{
PrintHintText(client, "Level your Tripmine first");
}
}
}
else if(ability==1)
{
if(!KillMine(client))
{
PrintHintText(client, "Plant a Landmine first");
}
}
}
else
{
War3_ChatMessage(client,"You can't lay a mine, your currently silenced!")
}
}
}
public bool:FilterAll(entity, contentsMask)
{
return false;
}
public bool:KillMine(client)
{
if(iMineOwner[client] > -1)
{
new mine = iMineOwner[client];
if(IsValidEdict(mine))
{
new Float:minepos[3];
new Float:enemypos[3];
new skill=War3_GetSkillLevel(client,thisRaceID,SKILL_MINE);
if(skill>0)
{
// Cooldown so it can't be placed again for 20 seconds
War3_CooldownMGR(client,20.0,thisRaceID,SKILL_MINE);
// now you can safely reset this variable:
iMineOwner[client] = -1;
GetEntPropVector(mine, Prop_Send, "m_vecOrigin", minepos);
TE_SetupExplosion(minepos, g_iExplosionModel, 20.0, 10, TE_EXPLFLAG_NONE, 300, 255);
TE_SendToAll();
TE_SetupSmoke(minepos, g_iExplosionModel, 100.0, 2);
TE_SendToAll();
TE_SetupSmoke(minepos, g_iSmokeModel, 100.0, 2);
TE_SendToAll();
AcceptEntityInput(mine, "Kill");
EmitSoundToAll(explodesnd,client);
// no reason to keep looping the client, when they client is always the same
new ClientTeam=GetClientTeam(client);
myLoopAlivePlayers(enemy)
{
if(GetClientTeam(enemy)==ClientTeam)
{
continue;
}
// I guess if the enemy is this race, then they are immune to mines?
// if this is true, try the mines against someone that is not this race for testing purposes
if(War3_GetRace(enemy)!=thisRaceID)
{
if(!W3HasImmunity(enemy,Immunity_Skills))
{
War3_CachedPosition(enemy,enemypos);
if(GetVectorDistance(minepos,enemypos)<=(MineRange[skill]*0.5))
{
War3_DealDamage( enemy, MineDamage[skill],client,DMG_BLAST,"Tripmine");
}
}
}
}
return true;
}
}
else
{
War3_ChatMessage(client,"Mine no longer is valid.");
}
iMineOwner[client] = -1;
}
return false;
}