Raised This Month: $46 Target: $400
 11% 

Updated "Superlogs" do not work!


Post New Thread Reply   
 
Thread Tools Display Modes
Author Message
tfp1
Junior Member
Join Date: Jan 2012
Old 01-23-2012 , 13:17   Updated "Superlogs" do not work!
Reply With Quote #1

I edited and recompiled the official "Superlogs"-Plugin for the mod "PVKII" to work with the "new" gamemode "Territory".

In "Territory", the three teams try to capture certain territories. The event allows me to retrieve all players who participated in the capture of a certain territory.

Here's the corresponding event: http://wiki.alliedmods.net/Pirates,_...ritory_capture

I marked the newly added parts bold. (There are only two new parts.)

I'm not a SourcePawn coder and I'm not a coder at all. I just read the scripting tutorials and tried to update the superlogs for my favorite game.


Code:
/**
 * HLstatsX Community Edition - SourceMod plugin to generate advanced weapon logging
 * http://www.hlxcommunity.com
 * Copyright (C) 2009-2010 Nicholas Hastings (psychonic)
 * Copyright (C) 2007-2008 TTS Oetzel & Goerz GmbH
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */

#pragma semicolon 1
 
#include <sourcemod>
#include <sdktools>

#define NAME "SuperLogs: PVKII"
#define VERSION "1.0.1"

#define MAX_LOG_WEAPONS 6
#define MAX_WEAPON_LEN 14


new g_weapon_stats[MAXPLAYERS+1][MAX_LOG_WEAPONS][15];
new const String:g_weapon_list[MAX_LOG_WEAPONS][MAX_WEAPON_LEN] = { 
                                    "blunderbuss",
                                    "flintlock",
                                    "arrow",
                                    "crossbow_bolt",
                                    "throwaxe",
                                    "javalin"
                                };
                                
new Handle:g_cvar_ktraj = INVALID_HANDLE;

new bool:g_logktraj = true;

new bool:g_bHasChest[MAXPLAYERS+1] = {false,...};
new bool:g_bHasGrail[MAXPLAYERS+1] = {false,...};

new g_iLastClass = -1;

new const String:g_szClassNames[][] = {
    "Skirmisher",
    "Captain",
    "",
    "Berserker",
    "Huscarl",
    "Gestir",
    "Heavy Knight",
    "Archer"
};

#define PVKII

#include <loghelper>
#include <wstatshelper>


public Plugin:myinfo = {
    name = NAME,
    author = "psychonic",
    description = "Advanced logging for PVKII. Generates auxilary logging for use with log parsers such as HLstatsX and Psychostats",
    version = VERSION,
    url = "http://www.hlxce.com"
};

#if SOURCEMOD_V_MAJOR >= 1 && SOURCEMOD_V_MINOR >= 3
public APLRes:AskPluginLoad2(Handle:myself, bool:late, String:error[], err_max)
#else
public bool:AskPluginLoad(Handle:myself, bool:late, String:error[], err_max)
#endif
{
    decl String:szGameDesc[64];
    GetGameDescription(szGameDesc, sizeof(szGameDesc), true);
    if (StrContains(szGameDesc, "PVKII", false) == -1)
    {
        decl String:szGameDir[64];
        GetGameFolderName(szGameDir, sizeof(szGameDir));
        if (StrContains(szGameDir, "pvkii", false) == -1)
        {
            strcopy(error, err_max, "This plugin is only supported on Pirate, Vikings, and Knights");
            #if SOURCEMOD_V_MAJOR >= 1 && SOURCEMOD_V_MINOR >= 3
                return APLRes_Failure;
            #else
                return false;
            #endif
        }
    }    
#if SOURCEMOD_V_MAJOR >= 1 && SOURCEMOD_V_MINOR >= 3
    return APLRes_Success;
#else
    return true;
#endif
}


public OnPluginStart()
{
    CreatePopulateWeaponTrie();
    
    g_cvar_ktraj = CreateConVar("superlogs_ktraj", "0", "Enable Psychostats \"KTRAJ\" logging (default off)", 0, true, 0.0, true, 1.0);
    HookConVarChange(g_cvar_ktraj, OnCvarKtrajChange);
    CreateConVar("superlogs_pvkii_version", VERSION, NAME, FCVAR_SPONLY|FCVAR_REPLICATED|FCVAR_NOTIFY);
    
    HookEvent("player_ranged_impact", Event_PlayerRangedImpact);
    HookEvent("player_death", Event_PlayerDeath);
    HookEvent("player_spawn", Event_PlayerSpawn);
    HookEvent("update_mvp_panel", Event_RoundEnd);
    HookEvent("player_disconnect", Event_PlayerDisconnect, EventHookMode_Pre);
    
    HookEvent("player_nemesis", Event_PlayerNemesis);
    HookEvent("player_revenge", Event_PlayerRevenge);
    HookEvent("player_objective", Event_PlayerObjective);
    HookEvent("grail_pickup", Event_GrailPickup);
    HookEvent("grail_drop", Event_GrailDrop);
    HookEvent("chest_pickup", Event_ChestPickup);
    HookEvent("chest_drop", Event_ChestDrop);
    HookEvent("chest_capture", Event_ChestCapture);
    HookEvent("gamemode_territory_capture", Event_TerritoryCapture); 
        
    CreateTimer(1.0, LogMap);
}

public OnMapStart()
{
    GetTeams();
}

public OnClientPutInServer(client)
{
    g_iLastClass = -1;
    reset_player_stats(client);
    g_bHasChest[client] = false;
    g_bHasGrail[client] = false;
}

public Event_PlayerNemesis(Handle:event, const String:name[], bool:dontBroadcast)
{
    LogPlyrPlyrEvent(GetClientOfUserId(GetEventInt(event, "userid")), GetClientOfUserId(GetEventInt(event, "victim")), "triggered", "domination");
}

public Event_PlayerRevenge(Handle:event, const String:name[], bool:dontBroadcast)
{
    LogPlyrPlyrEvent(GetClientOfUserId(GetEventInt(event, "userid")), GetClientOfUserId(GetEventInt(event, "victim")), "triggered", "revenge");
}

public Event_PlayerObjective(Handle:event, const String:name[], bool:dontBroadcast)
{
    LogPlayerEvent(GetClientOfUserId(GetEventInt(event, "userid")), "triggered", "obj_complete");
}

public Event_ChestPickup(Handle:event, const String:name[], bool:dontBroadcast)
{
    g_bHasChest[GetClientOfUserId(GetEventInt(event, "userid"))] = true;
}

public Event_ChestDrop(Handle:event, const String:name[], bool:dontBroadcast)
{
    g_bHasChest[GetClientOfUserId(GetEventInt(event, "userid"))] = false;
}

public Event_GrailPickup(Handle:event, const String:name[], bool:dontBroadcast)
{
    g_bHasGrail[GetClientOfUserId(GetEventInt(event, "userid"))] = true;
}

public Event_GrailDrop(Handle:event, const String:name[], bool:dontBroadcast)
{
    g_bHasGrail[GetClientOfUserId(GetEventInt(event, "userid"))] = false;
}

public Event_ChestCapture(Handle:event, const String:name[], bool:dontBroadcast)
{
    LogPlayerEvent(GetClientOfUserId(GetEventInt(event, "userid")), "triggered", "chest_capture");
}

public Event_TerritoryCapture(Handle:event, const String:name[], bool:dontBroadcast)
{
    new maxStrings = 256;
    new String:buffers[64][2];
    new String:IDs[] = "";
    GetEventString(event, "userids", IDs, 30);
    ExplodeString(IDs, ";", buffers, maxStrings, 2);
    for (new i=0; i<maxStrings; i++)
    {
        LogPlayerEvent(GetClientOfUserId(StringToInt(buffers[i])), "triggered", "gamemode_territory_capture");
    }    
}

public Event_PlayerRangedImpact(Handle:event, const String:name[], bool:dontBroadcast)
{
    // "userid"    "short"        // user ID of player who fired
    // "victim"    "short"        // entindex of entity that was hit (if any)
    // "weapon"    "string"    // weapon that was fired
    // "damage"    "float"        // how much damage was dealt, if 0 obviously missed or blocked by shield if victim is set
    
    new attacker = GetClientOfUserId(GetEventInt(event, "userid"));
    if (attacker == 0 || !IsClientInGame(attacker))
        return;
    
    decl String:weapon[MAX_WEAPON_LEN];
    GetEventString(event, "weapon", weapon, sizeof(weapon));
    new weapon_index = get_weapon_index(weapon);
    if (weapon_index == -1)
        return;
    
    if (!strcmp(weapon, "blunderbuss"))
    {
        // buckshot of 8
        g_weapon_stats[attacker][weapon_index][LOG_HIT_SHOTS] += 8;
    }
    else
    {
        g_weapon_stats[attacker][weapon_index][LOG_HIT_SHOTS]++;
    }
    
    new victim = GetEventInt(event, "victim");
    if (victim < 1 || victim > MaxClients || !IsClientInGame(victim))
        return;
    
    g_weapon_stats[attacker][weapon_index][LOG_HIT_HITS]++;
    g_weapon_stats[attacker][weapon_index][LOG_HIT_DAMAGE] += RoundToNearest(GetEventFloat(event, "damage"));
}

public Event_PlayerDeath(Handle:event, const String:name[], bool:dontBroadcast)
{
    // this extents the original player_death by a new fields
    // "userid"        "short"         // user ID who died                             
    // "attacker"      "short"         // user ID who killed
    // "weapon"        "string"        // weapon name killer used 
    
    new victim   = GetClientOfUserId(GetEventInt(event, "userid"));
    new attacker = GetClientOfUserId(GetEventInt(event, "attacker"));
    decl String: weapon[MAX_WEAPON_LEN];
    GetEventString(event, "weapon", weapon, sizeof(weapon));
    
    if (victim > 0 && attacker > 0)
    {
        new weapon_index = get_weapon_index(weapon);
        if (weapon_index > -1)
        {
            g_weapon_stats[attacker][weapon_index][LOG_HIT_KILLS]++;
            g_weapon_stats[victim][weapon_index][LOG_HIT_DEATHS]++;
            if (GetClientTeam(attacker) == GetClientTeam(victim))
            {
                g_weapon_stats[attacker][weapon_index][LOG_HIT_TEAMKILLS]++;
            }
        }
        dump_player_stats(victim);
        
        LogPlyrPlyrEvent(GetClientOfUserId(GetEventInt(event, "assistid")), victim, "triggered", "kill assist", true);
        
        if (g_bHasGrail[victim])
        {
            LogPlayerEvent(attacker, "triggered", "grail_defend");
        }
        if (g_bHasChest[victim])
        {
            LogPlayerEvent(attacker, "triggered", "chest_defend");
        }
        g_bHasGrail[victim] = false;
        g_bHasChest[victim] = false;
    }
    
    if (g_logktraj)
    {
        LogPSKillTraj(attacker, victim, weapon);
    }
}

public Event_PlayerSpawn(Handle:event, const String:name[], bool:dontBroadcast)
{
    // "userid"        "short"         // user ID on server          

    new client = GetClientOfUserId(GetEventInt(event, "userid"));
    if (client > 0)
    {
        reset_player_stats(client);
        if (IsClientInGame(client))
        {
            new iCurrentClass = GetEntProp(client, Prop_Send, "m_iPlayerClass");
            if (iCurrentClass > -1 && iCurrentClass != g_iLastClass)
            {
                LogRoleChange(client, g_szClassNames[iCurrentClass]);
            }
            g_iLastClass = iCurrentClass;
        }
    }
}

public Event_RoundEnd(Handle:event, const String:name[], bool:dontBroadcast)
{
    new winner = GetEventInt(event, "winner");
    if (winner > 1)
    {
        LogTeamEvent(winner, "triggered", "Round_Win");
    }
    
    LogPlayerEvent(GetEventInt(event, "pid_1"), "triggered", "mvp1");
    LogPlayerEvent(GetEventInt(event, "pid_2"), "triggered", "mvp2");
    LogPlayerEvent(GetEventInt(event, "pid_3"), "triggered", "mvp3");
    
    for (new i = 1; i <= MaxClients; i++)
    {
        g_bHasChest[i] = false;
        g_bHasGrail[i] = false;
    }
    
    WstatsDumpAll();
}

public Action:Event_PlayerDisconnect(Handle:event, const String:name[], bool:dontBroadcast)
{
    new client = GetClientOfUserId(GetEventInt(event, "userid"));
    OnPlayerDisconnect(client);
    return Plugin_Continue;
}


public Action:LogMap(Handle:timer)
{
    // Called 1 second after OnPluginStart since srcds does not log the first map loaded. Idea from Stormtrooper's "mapfix.sp" for psychostats
    LogMapLoad();
}

public OnCvarKtrajChange(Handle:cvar, const String:oldVal[], const String:newVal[])
{
    g_logktraj = GetConVarBool(g_cvar_ktraj);
}
(The plugin properly compiles, but doesn't work. Pleast help me to find out if I did something wrong in the code.)

Last edited by tfp1; 01-23-2012 at 13:19.
tfp1 is offline
McFlurry
Veteran Member
Join Date: Mar 2010
Location: RemoveEdict(0);
Old 01-23-2012 , 14:47   Re: Updated "Superlogs" do not work!
Reply With Quote #2

Try this
PHP Code:
public Event_TerritoryCapture(Handle:event, const String:name[], bool:dontBroadcast)
{
    new 
String:buffers[96][5]; //5 digits max in a userid by 16 which is >(256/(32/2)) + 16 semicolons
    
new String:IDs[256];
    
GetEventString(event"userids"IDssizeof(IDs));
    
ExplodeString(IDs";"bufferssizeof(buffers), sizeof(buffers[])); //I hope you know for sure that semicolons are the splitter
    
for (new i=0i<sizeof(buffers); i++)
    {
        
LogPlayerEvent(GetClientOfUserId(StringToInt(buffers[i])), "triggered""gamemode_territory_capture");
    }    

__________________

Last edited by McFlurry; 01-23-2012 at 15:43.
McFlurry is offline
Send a message via Skype™ to McFlurry
tfp1
Junior Member
Join Date: Jan 2012
Old 01-23-2012 , 15:35   Re: Updated "Superlogs" do not work!
Reply With Quote #3

Please bear with me.

  1. I assumed the UserIDs would be numbers in the region of playercount, e.g. "1" to "24" in this case.
  2. Wouldn't we receive a maximum of 23/24 semicolons with 24 participating players?
  3. I have no information about the splitters or the general string format of "userids"...

Last edited by tfp1; 01-23-2012 at 15:44.
tfp1 is offline
McFlurry
Veteran Member
Join Date: Mar 2010
Location: RemoveEdict(0);
Old 01-23-2012 , 15:41   Re: Updated "Superlogs" do not work!
Reply With Quote #4

1. Userids are 18 bit unsigned integers, client ids are 1 to number of max players.
2. Minor math error, change it to 95 if you want.
3. Use this to see the string printed to chat, this will print out the userids string then you can see if the splitter is a semicolon or a space.
PHP Code:
public Event_TerritoryCapture(Handle:event, const String:name[], bool:dontBroadcast)
{
    new 
String:buffers[96][5]; //5 digits max in a userid by 16 which is >(256/(32/2)) + 16 semicolons
    
new String:IDs[256];
    
GetEventString(event"userids"IDssizeof(IDs));
    
PrintToChatAll(IDs);
    
ExplodeString(IDs";"bufferssizeof(buffers), sizeof(buffers[])); //I hope you know for sure that semicolons are the splitter
    
for (new i=0i<sizeof(buffers); i++)
    {
        
LogPlayerEvent(GetClientOfUserId(StringToInt(buffers[i])), "triggered""gamemode_territory_capture");
    }    

__________________

Last edited by McFlurry; 01-23-2012 at 15:43.
McFlurry is offline
Send a message via Skype™ to McFlurry
tfp1
Junior Member
Join Date: Jan 2012
Old 01-23-2012 , 16:09   Re: Updated "Superlogs" do not work!
Reply With Quote #5

I assumed 5 (digits max) + 1 (semicolon) * 24 (players) = 144.

PHP Code:
public Event_TerritoryCapture(Handle:event, const String:name[], bool:dontBroadcast)
{
    new 
String:buffers[144][5]; //5 digits max in a userid by 16 which is >(256/(32/2)) + 16 semicolons
    
new String:IDs[256];
    
GetEventString(event"userids"IDssizeof(IDs));
    
PrintToChatAll(IDs);
    
ExplodeString(IDs";"bufferssizeof(buffers), sizeof(buffers[])); //I hope you know for sure that semicolons are the splitter
    
for (new i=0i<sizeof(buffers); i++)
    {
        
LogPlayerEvent(GetClientOfUserId(StringToInt(buffers[i])), "triggered""gamemode_territory_capture");
    }    

Is this wrong?

Sorry...
tfp1 is offline
McFlurry
Veteran Member
Join Date: Mar 2010
Location: RemoveEdict(0);
Old 01-23-2012 , 16:14   Re: Updated "Superlogs" do not work!
Reply With Quote #6

The max is based around the number of players that can capture a point at a time, if the max players is 24, and there are 3 teams, that means that if all teams are balanced 8 players is the max that can capture a point.
__________________
McFlurry is offline
Send a message via Skype™ to McFlurry
tfp1
Junior Member
Join Date: Jan 2012
Old 01-23-2012 , 16:32   Re: Updated "Superlogs" do not work!
Reply With Quote #7

I compiled it and tried it, but the added part didn't work and it didn't output anything to chat. The plugin itself was working just fine, it even triggered "obj_complete" (a.k.a. "player_objective" event) for the capturing player just fine.

Last edited by tfp1; 01-23-2012 at 16:35.
tfp1 is offline
McFlurry
Veteran Member
Join Date: Mar 2010
Location: RemoveEdict(0);
Old 01-23-2012 , 16:36   Re: Updated "Superlogs" do not work!
Reply With Quote #8

Which added part? Did the event itself not work?
__________________
McFlurry is offline
Send a message via Skype™ to McFlurry
tfp1
Junior Member
Join Date: Jan 2012
Old 01-23-2012 , 16:39   Re: Updated "Superlogs" do not work!
Reply With Quote #9

Yes, it didn't get triggered somehow.
tfp1 is offline
McFlurry
Veteran Member
Join Date: Mar 2010
Location: RemoveEdict(0);
Old 01-23-2012 , 16:42   Re: Updated "Superlogs" do not work!
Reply With Quote #10

It shouldn't have failed, unless you were accidentally running the wrong game mode. It could also be the event is broken.
__________________

Last edited by McFlurry; 01-23-2012 at 16:42.
McFlurry is offline
Send a message via Skype™ to McFlurry
Reply


Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -4. The time now is 18:02.


Powered by vBulletin®
Copyright ©2000 - 2020, vBulletin Solutions, Inc.
Theme made by Freecode