Member
|
07-26-2017
, 07:50
[TF2] Random shutdown server when creating landmine
|
#1
|
Hi, i created code, which creating landmine at the point which will detonate if enemy player trigger it(walk near landmine). Its working good, landmines creating and detonates, but sometimes randomly server shutdown when i creating new landmine or some of them detonate, without any error message...
I dont know where is the memory leak or something which shutdown server.
PHP Code:
new Float:l_mineHealth = 200.0;
new String:MODEL_MINE_RED[STRING_MAXLEN];
new String:MODEL_MINE_BLUE[STRING_MAXLEN];
new Float:l_mineDistance = 100.0;
new Float:l_mineDamage = 300.0;
new Float:l_mineRadiusDmg = 100.0;
new String:SOUND_MINE_CREATE[STRING_MAXLEN];
new String:SOUND_MINE_CATCH[STRING_MAXLEN];
new Handle:g_hMines = INVALID_HANDLE;
new Handle:g_hMinesTimer = INVALID_HANDLE;
enum l_eMine
{
Float:lm_iHealth,
lm_iEntity,
lm_iTeam,
Float:lm_fPos0,
Float:lm_fPos1,
Float:lm_fPos2,
lm_iOwner,
bool:lm_bExist,
};
new g_MineData[l_eMine];
void OnMapStart_mine()
{
PrecacheSound(SOUND_MINE_CREATE);
PrecacheModel(MODEL_MINE_RED);
PrecacheModel(MODEL_MINE_BLUE);
PrecacheModel(SOUND_MINE_CATCH);
OnRoundStarted_mine();
}
void OnRoundStarted_mine()
{
if(g_hMinesTimer != INVALID_HANDLE)
KillTimer(g_hMinesTimer);
g_hMinesTimer = INVALID_HANDLE;
if(g_hMines != INVALID_HANDLE)
if(GetArraySize(g_hMines) > 0)
{
for(int b = GetArraySize(g_hMines)-1; b >= 0; b--)
{
GetArrayArray(g_hMines, b, g_MineData, sizeof(g_MineData));
if(!g_MineData[lm_bExist])
continue;
if(g_MineData[lm_iEntity] > MaxClients)
{
SDKUnhook(g_MineData[lm_iEntity], SDKHook_OnTakeDamage, OnTakeDamage_mine);
RemoveEdict(g_MineData[lm_iEntity]);
//AcceptEntityInput(iData[l_iEntity], "Kill");
}
}
}
delete g_hMines;
g_hMines = CreateArray(l_eMine);
}
public Action:PlayerVoice_mine(client)
{
new Float:flPos[3];
if(GetClientLookPosition(client, flPos))
{
if(true/*CanBuildAtPosMineTrap(flPos)*/)
{
new iMine = SpawnMine(client, flPos);
if(iMine == -1)
{
EmitSoundToClient(client, SOUND_NOPE);
return Plugin_Handled;
}
EmitSoundToAll(SOUND_MINE_CREATE, client);
return Plugin_Handled;
}
}
EmitSoundToClient(client, SOUND_NOPE);
return Plugin_Handled;
}
stock int SpawnMine(builder, Float:Position[3])
{
new pEnt = CreateEntityByName("prop_dynamic");
if (pEnt == -1)
{
LogMessage("Mine failed to create.");
return -1;
}
int iTeam = GetClientTeam(builder);
g_MineData[lm_iTeam] = iTeam;
g_MineData[lm_iEntity] = pEnt;
g_MineData[lm_iHealth] = l_mineHealth;
g_MineData[lm_fPos0] = Position[0];
g_MineData[lm_fPos1] = Position[1];
g_MineData[lm_fPos2] = Position[2];
g_MineData[lm_iOwner] = builder;
g_MineData[lm_bExist] = true;
PushArrayArray(g_hMines, g_MineData, sizeof(g_MineData));
if(iTeam == TFTeam_Red)
DispatchKeyValue(pEnt, "model", MODEL_MINE_RED);
else
DispatchKeyValue(pEnt, "model", MODEL_MINE_BLUE);
SDKHook(pEnt, SDKHook_OnTakeDamage, OnTakeDamage_mine);
DispatchSpawn(pEnt);
TeleportEntity(pEnt, Position, NULL_VECTOR, NULL_VECTOR);
if(g_hMinesTimer == INVALID_HANDLE)
{
g_hMinesTimer = CreateTimer(0.25, Timer_mine, 0, TIMER_REPEAT);
}
return pEnt;
}
public Action:Timer_mine(Handle:hTimer, any:data)
{
if(GetArraySize(g_hMines) > 0)
{
for(int b = GetArraySize(g_hMines)-1; b >= 0; b--)
{
GetArrayArray(g_hMines, b, g_MineData, sizeof(g_MineData));
if(!g_MineData[lm_bExist])
{
RemoveFromArray(g_hMines, b);
continue;
}
for(new i=1; i<=MaxClients; i++)
{
if(IsClientInGame(i) && IsPlayerAlive(i) && GetClientTeam(i) != g_MineData[lm_iTeam])
{
if(!TF2_IsPlayerInCondition(i, TFCond_Ubercharged))
{
new Float:flPos2[3];
GetClientAbsOrigin(i, flPos2);
new Float:flPos1[3];
flPos1[0] = g_MineData[lm_fPos0];
flPos1[1] = g_MineData[lm_fPos1];
flPos1[2] = g_MineData[lm_fPos2];
new Float:flDistance = GetVectorDistance(flPos1, flPos2);
if(flDistance <= l_mineDistance)
{
if(!IsClientInGame(g_MineData[lm_iOwner]))
g_MineData[lm_iOwner] = 0;
new ent = g_MineData[lm_iEntity];
for(new c=1; c<=MaxClients; c++)
{
if(IsClientInGame(c) && IsPlayerAlive(c) && GetClientTeam(c) != g_MineData[lm_iTeam])
{
if(!TF2_IsPlayerInCondition(c, TFCond_Ubercharged))
{
GetClientAbsOrigin(c, flPos2);
flDistance = GetVectorDistance(flPos1, flPos2);
if(flDistance < l_mineRadiusDmg)
{
SDKHooks_TakeDamage(c, 0, g_MineData[lm_iOwner], l_mineDamage, DMG_PREVENT_PHYSICS_FORCE|DMG_CRUSH|DMG_ALWAYSGIB|DMG_BLAST);
}
}
}
}
int iExplosion = CreateParticleAtEntity(ent, "explosion");
if(iExplosion > MaxClients)
{
KillEntityDelay(iExplosion);
}
if(ent > MaxClients)
{
SDKUnhook(ent, SDKHook_OnTakeDamage, OnTakeDamage_mine);
RemoveEdict(ent);
//AcceptEntityInput(ent, "Kill");
}
//iData[l_bExist] = false;
//SetArrayArray(g_hMines, b, iData, sizeof(iData));
RemoveFromArray(g_hMines, b);
break;
}}}}}
return Plugin_Continue;
}
g_hMinesTimer = INVALID_HANDLE;
return Plugin_Stop;
}
Action:OnTakeDamage_mine(victim, &attacker, &inflictor, &Float:damage, &damagetype, &weapon, Float:damageForce[3], Float:damagePosition[3], damagecustom)
{
int id = FindValueInArray(g_hMines, victim, lm_iEntity);
if (id == -1)
return Plugin_Continue;
GetArrayArray(g_hMines, id, g_MineData, sizeof(g_MineData));
g_MineData[lm_iHealth] -= damage;
if(g_MineData[lm_iHealth] <= 0.0)
{
SDKUnhook(victim, SDKHook_OnTakeDamage, OnTakeDamage_mine);
RemoveEdict(victim);
g_MineData[lm_bExist] = false;
//RemoveFromArray(g_hMines, id);
}
SetArrayArray(g_hMines, id, g_MineData, sizeof(g_MineData));
return Plugin_Changed;
}
|
|