Fixed bugs in volfeatures. See details.

Fixed some anticamp bugs.
Warning types confirmed working: chat, center, menu (minior bug: the warning text is item no. 2).
Fixed base event handler bugs.
Added validation warnings on anticamp intervals in case of invalid intervals.
Fixed volume states not properly cleaned up when players die or disconnect.
This commit is contained in:
richard 2009-07-17 18:15:44 +02:00
parent 8127a29235
commit 1f38e9c5ac
6 changed files with 215 additions and 62 deletions

View File

@ -1104,6 +1104,12 @@
"Vol Slay" "Vol Slay"
{ {
"#format" "{1:s},{2:d}" "#format" "{1:s},{2:d}"
"en" "Player \"{1}\" has been slayed for camping in a restricted area (ID: {2})." "en" "Slayed player \"{1}\" for camping in a restricted area (ID: {2})."
}
"Vol Ignite"
{
"#format" "{1:s},{2:d}"
"en" "Ignited player \"{1}\" for camping in a restricted area (ID: {2})."
} }
} }

View File

@ -282,6 +282,7 @@ public Action:EventPlayerDeath(Handle:event, const String:name[], bool:dontBroad
ZSpawnOnClientDeath(index); ZSpawnOnClientDeath(index);
ZTeleOnClientDeath(index); ZTeleOnClientDeath(index);
ZHPOnClientDeath(index); ZHPOnClientDeath(index);
VolOnPlayerDeath(index);
} }
/** /**

View File

@ -77,6 +77,7 @@ new AnticampData[ZR_VOLUMES_MAX][VolTypeAnticamp];
VolAnticampEnable(volumeIndex) VolAnticampEnable(volumeIndex)
{ {
new Float:interval; new Float:interval;
new Handle:timer;
// Validate index. // Validate index.
if (!VolIsValidIndex(volumeIndex)) if (!VolIsValidIndex(volumeIndex))
@ -96,21 +97,28 @@ VolAnticampEnable(volumeIndex)
// Check if in use. // Check if in use.
if (AnticampData[dataindex][Anticamp_InUse]) if (AnticampData[dataindex][Anticamp_InUse])
{ {
// Start timer if not running. // Kill timer if it exist.
if (AnticampData[dataindex][Anticamp_Timer] == INVALID_HANDLE) timer = AnticampData[dataindex][Anticamp_Timer];
if (timer != INVALID_HANDLE)
{ {
KillTimer(timer);
AnticampData[dataindex][Anticamp_Timer] = INVALID_HANDLE;
}
// Get interval. // Get interval.
interval = AnticampData[dataindex][Anticamp_Interval]; interval = AnticampData[dataindex][Anticamp_Interval];
// Validate interval. // Validate interval.
if (interval > 0.0) if (interval > 0.0)
{ {
AnticampData[dataindex][Anticamp_Timer] = CreateTimer(interval, Event_VolAnticampTrigger, _, TIMER_REPEAT); AnticampData[dataindex][Anticamp_Timer] = CreateTimer(interval, Event_VolAnticampTrigger, volumeIndex, TIMER_REPEAT);
}
}
LogEvent(_, LogType_Normal, LOG_DEBUG, LogModule_Volfeatures, "Vol state", "Enabled anticamp volume %d.", volumeIndex); LogEvent(_, LogType_Normal, LOG_DEBUG, LogModule_Volfeatures, "Vol state", "Enabled anticamp volume %d.", volumeIndex);
} }
else
{
LogEvent(_, LogType_Error, LOG_CORE_EVENTS, LogModule_Volfeatures, "Config Validation", "Warning: Invalid interval %.2f in anticamp volume %d.", interval, volumeIndex);
}
}
} }
/** /**
@ -119,24 +127,44 @@ VolAnticampEnable(volumeIndex)
stock VolAnticampEnableAll() stock VolAnticampEnableAll()
{ {
new Float:interval; new Float:interval;
new dataindex;
// Loop through all volumes. // Loop through all volumes.
for (new dataindex = 0; dataindex < ZR_VOLUMES_MAX; dataindex++) for (new volumeindex = 0; volumeindex < ZR_VOLUMES_MAX; volumeindex++)
{ {
// Check if in use. // Check if unused.
if (AnticampData[dataindex][Anticamp_InUse]) if (!VolInUse(volumeindex))
{ {
// Start timer if not running. // Volume not in use, skip it.
if (AnticampData[dataindex][Anticamp_Timer] == INVALID_HANDLE) continue;
}
// Check if it's a anticamp volume.
if (VolIsType(volumeindex, VolFeature_Anticamp))
{ {
// Get data index.
dataindex = Volumes[volumeindex][Vol_DataIndex];
// Kill timer if it exist.
timer = AnticampData[dataindex][Anticamp_Timer];
if (timer != INVALID_HANDLE)
{
KillTimer(timer);
AnticampData[dataindex][Anticamp_Timer] = INVALID_HANDLE;
}
// Get interval. // Get interval.
interval = AnticampData[dataindex][Anticamp_Interval]; interval = AnticampData[dataindex][Anticamp_Interval];
// Validate interval. // Validate interval.
if (interval > 0.0) if (interval > 0.0)
{ {
AnticampData[dataindex][Anticamp_Timer] = CreateTimer(interval, Event_VolAnticampTrigger, _, TIMER_REPEAT); AnticampData[dataindex][Anticamp_Timer] = CreateTimer(interval, Event_VolAnticampTrigger, volumeindex, TIMER_REPEAT);
LogEvent(_, LogType_Normal, LOG_DEBUG, LogModule_Volfeatures, "Vol state", "Enabled anticamp volume %d.", volumeIndex);
} }
else
{
LogEvent(_, LogType_Error, LOG_CORE_EVENTS, LogModule_Volfeatures, "Config Validation", "Warning: Invalid interval %.2f in anticamp volume %d.", interval, volumeIndex);
} }
} }
} }
@ -242,23 +270,37 @@ VolAnticampInit()
/** /**
* Timer callback for anticamp volumes. Applies actions on players in volumes. * Timer callback for anticamp volumes. Applies actions on players in volumes.
*/ */
public Action:Event_VolAnticampTrigger(Handle:timer) public Action:Event_VolAnticampTrigger(Handle:timer, any:volumeIndex)
{ {
// Loop through all players. // Loop through all players.
for (new client = 1; client <= MaxClients; client++) for (new client = 1; client <= MaxClients; client++)
{ {
// Loop through all volumes. // Validate client's connection state.
for (new volumeindex = 0; volumeindex < ZR_VOLUMES_MAX; volumeindex++) if (!IsClientConnected(client) || !IsClientInGame(client) || !IsPlayerAlive(client))
{ {
// Check if the volume is enabled and in use. continue;
if (VolIsEnabled(volumeindex) && VolInUse(volumeindex)) }
// Check if the volume is unused.
if (!VolInUse(volumeIndex))
{ {
// Check if player is in a anticamp volume. continue;
if (VolPlayerInVolume[client][volumeindex] && Volumes[volumeindex][Vol_Type] == VolFeature_Anticamp) }
// Check if the volume is disabled.
if (!VolIsEnabled(volumeIndex))
{
continue;
}
// Check if it's a anticamp volume.
if (VolIsType(volumeIndex, VolFeature_Anticamp))
{
// Check if player is in the volume.
if (VolPlayerInVolume[client][volumeIndex])
{ {
// Apply action. // Apply action.
VolAnticampApplyAction(client, Volumes[volumeindex][Vol_DataIndex], volumeindex); VolAnticampApplyAction(client, Volumes[volumeIndex][Vol_DataIndex], volumeIndex);
}
} }
} }
} }
@ -275,6 +317,13 @@ VolAnticampApplyAction(client, dataIndex, volumeIndex)
{ {
new Float:amount = AnticampData[dataIndex][Anticamp_Amount]; new Float:amount = AnticampData[dataIndex][Anticamp_Amount];
// Set client language.
SetGlobalTransTarget(client);
// Get player name.
decl String:name[64];
GetClientName(client, name, sizeof(name));
// Send warning message. // Send warning message.
VolAnticampWarnPlayer(client, dataIndex); VolAnticampWarnPlayer(client, dataIndex);
@ -286,11 +335,9 @@ VolAnticampApplyAction(client, dataIndex, volumeIndex)
} }
case Anticamp_Damage: case Anticamp_Damage:
{ {
// Give damage to player. Kill if zero HP. // Give damage to player. Kill if zero HP or below.
new damage = RoundToNearest(amount); new damage = RoundToNearest(amount);
new health = GetClientHealth(client) - damage; new health = GetClientHealth(client) - damage;
decl String:name[64];
decl String:buffer[256];
if (health > 0) if (health > 0)
{ {
@ -302,29 +349,32 @@ VolAnticampApplyAction(client, dataIndex, volumeIndex)
ForcePlayerSuicide(client); ForcePlayerSuicide(client);
// Log event. // Log event.
GetClientName(client, name, sizeof(name)); LogEvent(false, LogType_Normal, LOG_GAME_EVENTS, LogModule_Volfeatures, "Anti-camp", "%t", "Vol Slay", name, volumeIndex);
SetGlobalTransTarget(client);
Format(buffer, sizeof(buffer), "%t", "Vol Slay", name, volumeIndex);
/*if (LogFlagCheck(LOG_GAME_EVENTS, LOG_MODULE_ANTICAMP)) ZR_LogMessageFormatted(client, "anticamp", "kill", "%s", true, buffer);
if (anticamp_echo)
{
FormatTextString(buffer, sizeof(buffer));
ZR_PrintToAdminChat(buffer);
}*/
} }
} }
case Anticamp_Slay: case Anticamp_Slay:
{ {
// Instantly kill the player.
ForcePlayerSuicide(client);
// Log event.
LogEvent(false, LogType_Normal, LOG_GAME_EVENTS, LogModule_Volfeatures, "Anti-camp", "%t", "Vol Slay", name, volumeIndex);
} }
case Anticamp_Drug: case Anticamp_Drug:
{ {
// TODO: Trigger sm_drug on client some how.
} }
case Anticamp_Ignite: case Anticamp_Ignite:
{ {
// Validate amount.
if (amount > 0.0)
{
// Ignite player for "amount" seconds.
IgniteEntity(client, amount);
// Log event.
LogEvent(false, LogType_Normal, LOG_GAME_EVENTS, LogModule_Volfeatures, "Anti-camp", "%t", "Vol Ignite", name, volumeIndex);
}
} }
} }
} }
@ -351,7 +401,7 @@ VolAnticampWarnPlayer(client, dataIndex)
} }
else else
{ {
// Use message in translations file. // Use default anticamp message in translations file.
Format(buffer, sizeof(buffer), "%t", "Vol Anticamp Message"); Format(buffer, sizeof(buffer), "%t", "Vol Anticamp Message");
} }
@ -415,6 +465,10 @@ VolAnticampGetFreeIndex()
// Check if it's free. // Check if it's free.
if (!AnticampData[dataindex][Anticamp_InUse]) if (!AnticampData[dataindex][Anticamp_InUse])
{ {
// Mark as in use.
AnticampData[dataindex][Anticamp_InUse] = true;
// Return the new index.
return dataindex; return dataindex;
} }
} }

View File

@ -223,7 +223,6 @@ public Action:VolAddVolumeCommand(client, argc)
// Set attributes. // Set attributes.
paramcount = VolSetAttributes(volindex, params); paramcount = VolSetAttributes(volindex, params);
LogEvent(_, LogType_Normal, LOG_DEBUG, LogModule_Volfeatures, "Add volume", "Parsing parameter string. Param count = \"%d\". String = \"%s\"", paramcount, params);
} }
else else
{ {
@ -240,6 +239,9 @@ public Action:VolAddVolumeCommand(client, argc)
Format(buffer, sizeof(buffer), "Additional attributes set: %d", paramcount); Format(buffer, sizeof(buffer), "Additional attributes set: %d", paramcount);
} }
// Send enable event to volume.
VolOnEnabled(volindex);
ReplyToCommand(client, "Added volume at index %d. %s", volindex, buffer); ReplyToCommand(client, "Added volume at index %d. %s", volindex, buffer);
return Plugin_Handled; return Plugin_Handled;
} }

View File

@ -85,6 +85,38 @@ VolOnPlayerSpawn(client)
VolUpdatePlayerLocation(client); VolUpdatePlayerLocation(client);
} }
/**
* Called when a player died.
*
* @param client The client index.
*/
VolOnPlayerDeath(client)
{
// Send player left volume event to all volumes the player was in.
for (new volindex = 0; volindex < ZR_VOLUMES_MAX; volindex++)
{
// Check if volume is unused.
if (!Volumes[volindex][Vol_InUse])
{
continue;
}
// Check if volume is disabled.
if (!Volumes[volindex][Vol_Enabled])
{
continue;
}
// Check if player is inside the volume.
if (VolPlayerInVolume[client][volindex])
{
// Mark as not in the volume and trigger event.
VolPlayerInVolume[client][volindex] = false;
VolOnPlayerLeave(client, volindex);
}
}
}
/** /**
* Called when a player disconnects. * Called when a player disconnects.
* *
@ -94,6 +126,9 @@ VolOnPlayerDisconnect(client)
{ {
// Disable trigger delay counters. // Disable trigger delay counters.
VolResetCountDown(client); VolResetCountDown(client);
// Trigger death event to clean up.
VolOnPlayerDeath(client);
} }
/** /**
@ -133,6 +168,13 @@ VolOnRoundEnd()
*/ */
VolOnDisabled(volumeIndex) VolOnDisabled(volumeIndex)
{ {
// Check if volumetric features is enabled.
if (!VolEnabled)
{
// Volumetric features disabled.
return;
}
new VolumeFeatureTypes:voltype = Volumes[volumeIndex][Vol_Type]; new VolumeFeatureTypes:voltype = Volumes[volumeIndex][Vol_Type];
// Forward stop event to features. // Forward stop event to features.
@ -151,6 +193,13 @@ VolOnDisabled(volumeIndex)
*/ */
VolOnEnabled(volumeIndex) VolOnEnabled(volumeIndex)
{ {
// Check if volumetric features is enabled.
if (!VolEnabled)
{
// Volumetric features disabled.
return;
}
new VolumeFeatureTypes:voltype = Volumes[volumeIndex][Vol_Type]; new VolumeFeatureTypes:voltype = Volumes[volumeIndex][Vol_Type];
// Forward stop event to features. // Forward stop event to features.

View File

@ -195,6 +195,28 @@ VolDisableVolumes()
{ {
if (Volumes[volindex][Vol_InUse] && Volumes[volindex][Vol_Enabled]) if (Volumes[volindex][Vol_InUse] && Volumes[volindex][Vol_Enabled])
{ {
// Mark as disabled.
Volumes[volindex][Vol_Enabled] = false;
// Trigger player left volume event if inside a volume.
for (new client = 1; client <= MaxClients; client++)
{
// Validate client's connection state.
if (!IsClientConnected(client) || !IsClientInGame(client))
{
continue;
}
// Check if player is inside the volume.
if (VolPlayerInVolume[client][volindex])
{
// Mark as not in the volume and trigger event.
VolPlayerInVolume[client][volindex] = false;
VolOnPlayerLeave(client, volindex);
}
}
// Trigger disabled event.
VolOnDisabled(volindex); VolOnDisabled(volindex);
} }
} }
@ -210,6 +232,7 @@ VolEnableVolumes()
{ {
if (Volumes[volindex][Vol_InUse] && !Volumes[volindex][Vol_Enabled]) if (Volumes[volindex][Vol_InUse] && !Volumes[volindex][Vol_Enabled])
{ {
Volumes[volindex][Vol_Enabled] = true;
VolOnEnabled(volindex); VolOnEnabled(volindex);
} }
} }
@ -367,10 +390,10 @@ VolUpdatePlayerLocation(client = -1)
{ {
for (client = 1; client <= MaxClients; client++) for (client = 1; client <= MaxClients; client++)
{ {
// Check if client is in game and alive. // Validate client's connection state.
if (!IsClientConnected(client) || !IsClientInGame(client) || !IsPlayerAlive(client)) if (!IsClientConnected(client) || !IsClientInGame(client) || !IsPlayerAlive(client))
{ {
return; continue;
} }
// Save location in array. // Save location in array.
@ -396,7 +419,7 @@ VolUpdatePlayerChanges()
// Loop through all players. // Loop through all players.
for (new client = 1; client <= MaxClients; client++) for (new client = 1; client <= MaxClients; client++)
{ {
// Check if client is in game and alive. // Validate client's connection state.
if (!IsClientConnected(client) || !IsClientInGame(client) || !IsPlayerAlive(client)) if (!IsClientConnected(client) || !IsClientInGame(client) || !IsPlayerAlive(client))
{ {
// Skip client. // Skip client.
@ -467,6 +490,11 @@ VolUpdatePlayerChanges()
// Make sure count down value is reset. // Make sure count down value is reset.
VolPlayerCountDown[client][volumeIndex] = -1.0; VolPlayerCountDown[client][volumeIndex] = -1.0;
// Only trigger left volume event if player already is in the
// volume, so volumes with trigger delay won't get a left event
// before the enter event.
if (VolPlayerInVolume[client][volumeIndex])
{
// Update cache. // Update cache.
VolPlayerInVolume[client][volumeIndex] = false; VolPlayerInVolume[client][volumeIndex] = false;
@ -476,6 +504,7 @@ VolUpdatePlayerChanges()
} }
} }
} }
}
/** /**
* Returns wether a point is within a certain location. * Returns wether a point is within a certain location.
@ -641,6 +670,18 @@ bool:VolTeamFilterMatch(client, volumeIndex)
return false; return false;
} }
/**
* Checs if a volume is a certain type.
*
* @param volumeIndex Volume to check.
* @param volType Type to match.
* @return True if the types match, false otherwise.
*/
bool:VolIsType(volumeIndex, VolumeFeatureTypes:volType)
{
return Volumes[volumeIndex][Vol_Type] == volType;
}
/** /**
* Gets wether a client is within volumes or not. Result is stored in a boolean * Gets wether a client is within volumes or not. Result is stored in a boolean
* array. * array.