I'm currently having two problems:
1. I have the following code to equip players in a custom Arena round:
PHP Code:
...
new BlueTeam[32], RedTeam[32], BlueCounter, RedCounter;
for (new i = 1; i <= MaxClients; i++)
{
// It seems that respawning all the players at this point ends the round instantly in a stalemate.
// Instead, we need to go with the numbers of players on each team (which should be equal) and change
// their classes.
if ( IsClientInGame(i) )
{
switch (GetClientTeam(i))
{
case TEAM_RED:
{
RedTeam[RedCounter] = i;
RedCounter++;
}
case TEAM_BLUE:
{
BlueTeam[BlueCounter] = i;
BlueCounter++;
}
}
}
}
for ( new red = 0; red < RedCounter; red++ )
{
SetEntProp(RedTeam[red], Prop_Send, "m_lifeState", 2); // Manually set the lifestate so that changing class doesn't cause us to die.
TF2_SetPlayerClass(RedTeam[red], TFClass_Heavy);
SetEntProp(RedTeam[red], Prop_Send, "m_lifeState", 0); // NOTE: Will this properly replace things like hats?? D:
TF2_RemoveAllWeapons(RedTeam[red]); // Trash all the player's weapons.
}
for ( new blue = 0; blue < BlueCounter; blue++ )
{
SetEntProp(BlueTeam[blue], Prop_Send, "m_lifeState", 2);
TF2_SetPlayerClass(BlueTeam[blue], TFClass_Pyro);
SetEntProp(BlueTeam[blue], Prop_Send, "m_lifeState", 0);
TF2_RemoveAllWeapons(BlueTeam[blue]); // Trash all the player's weapons.
}
// Set up a timer to re-equip all players.
// It seems that if we try and re-equip right here after weapons have been stripped,
// players end up with no weapons at all.
// EDIT: THIS STILL HAPPENS :C
CreateTimer(0.1, Timer_EquipPlayers);
...
/* Equips players asynchronously. */
public Action:Timer_EquipPlayers(Handle:timer)
{
if ( !g_bPluginState ) return;
// Rebuild our previous data.
new BlueTeam[32], RedTeam[32], BlueCounter, RedCounter;
for (new i = 1; i <= MaxClients; i++)
{
if ( IsClientInGame(i) && IsPlayerAlive(i) ) // Don't include dead players for equipping
{
switch (GetClientTeam(i))
{
case TEAM_RED:
{
RedTeam[RedCounter] = i;
RedCounter++;
}
case TEAM_BLUE:
{
BlueTeam[BlueCounter] = i;
BlueCounter++;
}
}
}
}
for ( new red = 0; red < RedCounter; red++ )
{
new Handle:hItem = TF2Items_CreateItem(OVERRIDE_ALL); // Create a new TF2Items handle for our new weapon, overriding all attributes.
// Set up the KGB:
TF2Items_SetClassname(hItem, "tf_weapon_fists"); // Based off fists;
TF2Items_SetItemIndex(hItem, 43); // Item def index 43;
TF2Items_SetQuality(hItem, 0); // Normal quality;
TF2Items_SetLevel(hItem, 7); // Level 7 (limited according to items_game.txt).
TF2Items_SetNumAttributes(hItem, 2); // Two attributes for the KGB:
TF2Items_SetAttribute(hItem, 0, 31, 5.0); // Crit boost on kill,
TF2Items_SetAttribute(hItem, 1, 5, 1.2); // Fire rate penalty.
TF2Items_GiveNamedItem(RedTeam[red], hItem); // Give the item.
CloseHandle(hItem); // Close the handle.
}
new bool:LastPyroWeapon = true; // False = Volcano Fragment, true = Axetinguisher. We always want to give VFs first, since they do more reliable damage.
for ( new blue = 0; blue < BlueCounter; blue++ )
{
new Handle:hItem = TF2Items_CreateItem(OVERRIDE_ALL); // Create a new TF2Items handle for our new weapon, overriding all attributes.
if ( LastPyroWeapon ) // If the last weapon was an Axetinguisger, set up the Volcano Fragment.
{
TF2Items_SetClassname(hItem, "tf_weapon_fireaxe"); // Based off fireaxe;
TF2Items_SetItemIndex(hItem, 348); // Item def index 348;
TF2Items_SetQuality(hItem, 0); // Normal quality;
TF2Items_SetLevel(hItem, 10); // Level 10 (limited according to items_game.txt).
TF2Items_SetNumAttributes(hItem, 2); // Two attributes for the Volcano Fragment:
TF2Items_SetAttribute(hItem, 0, 208, 1.0); // Ignite on kill,
TF2Items_SetAttribute(hItem, 1, 1, 0.8); // Damage penalty.
LastPyroWeapon = false; // Record the weapon we just created.
}
else // If the last weapon was a Volcano Fragment, set up the Axetinguisher.
{
TF2Items_SetClassname(hItem, "tf_weapon_fireaxe"); // Based off fireaxe;
TF2Items_SetItemIndex(hItem, 38); // Item def index 38;
TF2Items_SetQuality(hItem, 0); // Normal quality;
TF2Items_SetLevel(hItem, 10); // Level 10 (limited according to items_game.txt).
TF2Items_SetNumAttributes(hItem, 3); // Three attributes for the Axetinguisher:
TF2Items_SetAttribute(hItem, 0, 20, 1.0); // Crits vs. burning players,
TF2Items_SetAttribute(hItem, 1, 21, 0.5); // Dmg vs. non-burning players,
TF2Items_SetAttribute(hItem, 2, 22, 1.0); // No crits vs. non-burning players.
LastPyroWeapon = true; // Record the weapon we just created.
}
TF2Items_GiveNamedItem(BlueTeam[blue], hItem); // Give the item.
CloseHandle(hItem); // Close the handle.
}
}
The multiple "for" loops, in case anyone's wondering, were previously used for applying the "if class = pyro" situation from above to other classes, where the given weapons needed to be alternated and so a contiguous list of each team was required.
However, when it's all executed players are left with no items despite it all. I end up with the weapon model of the weapon I was holding but it doesn't do anything, and all other players are in the reference pose.
2. I have a host plugin which informs other, dependant plugins through forwards if it gets unloaded, or loaded again. This was in the hopes of allowing dependant plugins to shut off any custom tasks they're performing if the host plugin is unloaded, and to be notified of it if it came back again. The following is the host code:
PHP Code:
...
fw_HLoad = CreateGlobalForward("ArenaMod_HandlerLoad", ET_Ignore);
fw_HUnload = CreateGlobalForward("ArenaMod_HandlerUnload", ET_Ignore);
...OnAllPluginsLoaded()...
// Notify custom modes that we have loaded.
Call_StartForward(fw_HLoad); // Notify custom modes that we are loading.
Call_Finish();
...
public OnPluginEnd()
{
Call_StartForward(fw_HUnload); // Notify custom modes that we are unloading.
Call_Finish();
}
And child plugin's code:
PHP Code:
/* The main handler has loaded. Don't do custom setup here, just update the AMLibExists flag. */
public ArenaMod_HandlerLoad()
{
LogMessage("Handler load detected.");
AMLibExists = true;
}
/* This means that the handler has unloaded and all modes should clean up their resources. */
public ArenaMod_HandlerUnload()
{
LogMessage("Handler unload detected, base mode will clean up resources here.");
g_bPluginState = false;
ModeID = -10;
AMLibExists = false;
}
If I load up a server, all the forwards are responded to from the host. When I unload the host, I see the "notified of unload" message from the child plugin. However, if I then go to reload the host no forwards are acted upon whatsoever by any child plugins, even after changing map etc. Is there a way to fix this?
Thanks.