Raised This Month: $32 Target: $400
 8% 

[TF2] Player-Following Annotations Snippet


Post New Thread Reply   
 
Thread Tools Display Modes
Author Message
404UserNotFound
BANNED
Join Date: Dec 2011
Old 12-29-2013 , 17:59   [TF2] Player-Following Annotations Snippet
Reply With Quote #1

So I started working on something I was calling Admin Anno-tags (combination of Annotation and Tags). Then I ran into an issue where the annotations were visible through walls, and at any distance, so I gave up on it.

I also originally had some code in there to hide the annotations when a player died, but I didn't do it properly, so if a player died, all annotations would disappear for them. Once an admin respawned, the annotations would re-appear to that player. It was incredibly glitchy. So I commented it out.

Luckily, I was smart enough to keep the code, so I've decided to post it here. I know that Geit's Annotations plugin was unapproved, and people are wanting that to be fixed, so hopefully my code can be of some use.

NOTE 1: Some code was taken from that excellent Gravestone Markers plugin made by Friagram, in regards to the Bitstring stuff, that I was having trouble with.

NOTE 2: If you do make a plugin using any of this code, you do NOT have to give me credit. You can if you want to, but I don't find it necessary. Do give credit to Friagram though, he deserves it!

PHP Code:
// Massive credit to Friagram for his Gravestone Markers plugin. Without that, I wouldn't have gotten this far!

#include <sourcemod>
#include <sdktools>
#include <tf2_stocks>

#pragma semicolon 1

#define PLUGIN_VERSION "1.0"
#define SOUND_NULL    "vo/null.wav"

public Plugin:myinfo =
{
    
name "[WIP] Annotation Admin Tags",
    
author "abrandnewday",
    
description "Adds neat little annotation tags for admins",
    
version PLUGIN_VERSION,
}

public 
OnPluginStart()
{
    
HookEvent("player_spawn"Event_PlayerSpawn);
//    HookEvent("player_death", Event_PlayerDeath);
}

/*
// Event: Plugin has been unloaded, hide annotations.
public OnPluginEnd()
{
    for (new i=1; i <= MaxClients; i++)
    {
        HideAnnotation(i);
    }
}
*/

// Event: Player has spawned, check if they're an admin, and if so, assign the annotation.
public Action:Event_PlayerSpawn(Handle:event, const String:name[], bool:dontBroadcast
{
    new 
user GetEventInt(event"userid");
    new 
client GetClientOfUserId(user);
    
    if(
GetUserFlagBits(client) && ADMFLAG_GENERIC
    {
        
ShowAnnotation(client);
    }
    return 
Plugin_Continue;
}

/*
// Event: Player has died, hide the annotation.
public Action:Event_PlayerDeath(Handle:event, const String:name[], bool:dontBroadcast)
{
    new user = GetEventInt(event, "userid");
    new client = GetClientOfUserId(user);

    if(GetUserFlagBits(client) && ADMFLAG_GENERIC)
    {
        HideAnnotation(client);
    }
    return Plugin_Continue;
}
*/

// Function: Show the annotation!
ShowAnnotation(client)
{
    for (new 
i=1<= MaxClientsi++)
    {
        new 
bitstring RoundFloat(Pow(2.0float(i)));
        if (
bitstring 1)
        {
            new 
Handle:event CreateEvent("show_annotation");
            if (
event != INVALID_HANDLE)
            {
                
SetEventFloat(event"lifetime"999999.0); // Long-ass lifetime.
                
SetEventInt(event"id"i);
                
SetEventString(event"text""Admin"); // Displays "Admin" in the annotation
                
SetEventInt(event"visibilityBitfield"bitstring);
                
SetEventInt(event"follow_entindex"client); // Follow the player
                
SetEventString(event"play_sound"SOUND_NULL);
                
SetEventBool(event"show_distance"100); // Not sure what the distance is measured in
                
FireEvent(event);
            }
        }
    }
}

/*
// Function: Hide Annotation
HideAnnotation(client)
{
    new Handle:event = CreateEvent("hide_annotation");
    if(event == INVALID_HANDLE) return;
    SetEventInt(event, "id", client);
    FireEvent(event);
}
*/

// Function: Build Bitstring for visibility
public BuildBitString(Float:position[3])
{
    new 
bitstring 1;
    for (new 
client=1client <= MaxClientsclient++)
    {
        if (
IsClientInGame(client))
        {
            
decl Float:EyePos[3];
            
GetClientEyePosition(clientEyePos);
            if (
GetVectorDistance(positionEyePos) < 400)
            {
                
bitstring |= RoundFloat(Pow(2.0float(client)));
            }
        }
    }
    return 
bitstring;
}

/*
// Old bitstring code I used to use.
DoFilter(client)
{
    new bitstring;
    for(new viewer = 1; viewer <= MaxClients; viewer++)
    {
        if(client == viewer) continue;
        if(IsClientInGame(viewer) && IsPlayerAlive(viewer) && IsWithinRange(client, viewer))
        {
            bitstring |= (1 << viewer);
        }
    }
    return bitstring;
}

bool:IsWithinRange(client, viewer)
{
    new Float:clientpos[3], Float:viewerpos[3];
    GetClientAbsOrigin(client, clientpos);
    GetClientAbsOrigin(viewer, viewerpos);
    if(GetVectorDistance(clientpos, viewerpos) <= 500.0) return true;
    else return false;

*/ 

Last edited by 404UserNotFound; 12-29-2013 at 18:00.
404UserNotFound is offline
friagram
Veteran Member
Join Date: Sep 2012
Location: Silicon Valley
Old 12-30-2013 , 06:06   Re: [TF2] Player-Following Annotations Snippet
Reply With Quote #2

...
You need to do something like what I did here to make these work properly: https://forums.alliedmods.net/showthread.php?p=1946768
__________________
Profile - Plugins
Add me on steam if you are seeking sp/map/model commissions.
friagram is offline
404UserNotFound
BANNED
Join Date: Dec 2011
Old 12-30-2013 , 10:49   Re: [TF2] Player-Following Annotations Snippet
Reply With Quote #3

Quote:
Originally Posted by friagram View Post
...
You need to do something like what I did here to make these work properly: https://forums.alliedmods.net/showthread.php?p=1946768
I used snippets from your plugin. Everything works correctly except for the visibility bitfield.

But hey, it's not my problem anymore. Hooray for public access!

Last edited by 404UserNotFound; 12-30-2013 at 10:50.
404UserNotFound is offline
Mitchell
~lick~
Join Date: Mar 2010
Old 12-30-2013 , 11:58   Re: [TF2] Player-Following Annotations Snippet
Reply With Quote #4

Mind explaining how the visibility Field works?
Mitchell is offline
404UserNotFound
BANNED
Join Date: Dec 2011
Old 12-30-2013 , 12:31   Re: [TF2] Player-Following Annotations Snippet
Reply With Quote #5

Quote:
Originally Posted by Mitchell View Post
Mind explaining how the visibility Field works?
I'm not really sure how, that's more or less Friagram's area of expertise. The code was taken from his gravestone plugin, and modified so it didn't use a convar. For some reason though, the annotations would stay visible even if you were to noclip WAY out into the void of a map.

The original visibility bitstring code that is commented out at the bottom, I believe that worked.

I'm no expert in this annotation and bitstring stuff, but I just love the idea of it. I mean, it could be used in plugins like VS Saxton Hale/Freak Fortress 2 (i.e. when the boss is visible to a player, have an annotation follow the boss that says the bosses name, such as "Saxton Hale!" or "Horsemann Jr!")

EDIT: Oh, and as mentioned in the main post, my code is a tad wonky, so if an admin spawns, the tag becomes visible to people. But if an admin dies (with the player_death code uncommented) all the annotations on every admin disappear. From there, an admin has to respawn for the tag to become visible. I have no clue how to make annotations with differential IDs so that if Admin A dies, the annotations on Admin B/C/etc don't disappear from everyone's view.

Last edited by 404UserNotFound; 12-30-2013 at 12:39.
404UserNotFound is offline
Mitchell
~lick~
Join Date: Mar 2010
Old 12-30-2013 , 13:30   Re: [TF2] Player-Following Annotations Snippet
Reply With Quote #6

I was asking because i want to make an annotation that only certain players can see over another player's head.
Mitchell is offline
404UserNotFound
BANNED
Join Date: Dec 2011
Old 12-30-2013 , 13:33   Re: [TF2] Player-Following Annotations Snippet
Reply With Quote #7

Quote:
Originally Posted by Mitchell View Post
I was asking because i want to make an annotation that only certain players can see over another player's head.
Hmm....yeah, I'm not exactly sure. Sorry

EDIT: Actually, I think I may have an idea. Gimme a mo!

PHP Code:
public BuildBitString(Float:position[3])
{
    new 
bitstring 1;
    for (new 
client=1client <= MaxClientsclient++)
    {
        
// Check if client is ingame, and is a donator. Not sure if this'd work though.
        
if (IsClientInGame(client) && GetUserFlagBits(client) && ADMFLAG_CUSTOM1)
        {
            
decl Float:EyePos[3];
            
GetClientEyePosition(clientEyePos);
            if (
GetVectorDistance(positionEyePos) < 400)
            {
                
bitstring |= RoundFloat(Pow(2.0float(client)));
            }
        }
    }
    return 
bitstring;


Last edited by 404UserNotFound; 12-30-2013 at 13:35.
404UserNotFound is offline
Mitchell
~lick~
Join Date: Mar 2010
Old 12-30-2013 , 13:52   Re: [TF2] Player-Following Annotations Snippet
Reply With Quote #8

Just making sure, ill have to test this at a later moment but say if i want to show it to only one player i would just make the bitstring: "2^(clientindex)" correct?
Mitchell is offline
404UserNotFound
BANNED
Join Date: Dec 2011
Old 12-30-2013 , 14:51   Re: [TF2] Player-Following Annotations Snippet
Reply With Quote #9

Quote:
Originally Posted by Mitchell View Post
Just making sure, ill have to test this at a later moment but say if i want to show it to only one player i would just make the bitstring: "2^(clientindex)" correct?
Uh.....I don't know.....I'm not at that level of coding
404UserNotFound is offline
Powerlord
AlliedModders Donor
Join Date: Jun 2008
Location: Seduce Me!
Old 12-30-2013 , 16:34   Re: [TF2] Player-Following Annotations Snippet
Reply With Quote #10

Quote:
Originally Posted by Mitchell View Post
Just making sure, ill have to test this at a later moment but say if i want to show it to only one player i would just make the bitstring: "2^(clientindex)" correct?
For bitfields, why not just use (left) bitshifting? That's what it exists for.

The only catch is that I'm not sure if it counts from 0 or not.

So, here's both versions... try both and see if they work.
PHP Code:
new bitfield 0;

// Iterating through all clients to build a visibility bitfield of all alive players
for (new client 1client <= MaxClientsi++)
{
    if (
IsClientInGame(client) && IsPlayerAlive(client))
    {
         
// 1-based
        
bitfield |= (<< client);
        
// 0-based
        //bitfield |= (1 << (client - 1));
    
}
}

// or for a single client

new bitfield = (<< client); 
(I'm assuming 1-based is correct based on glancing at the gravestone plugin's BuildBitString)

Edit: For those of you who don't know what bitshifting does, I'll give a quick example.

Pretend this is a series of 8 bits: 0b00000000 (0b is used to denote it's binary... it's a GCC thing)
Like a standard decimal, the lowest number is the one at the far right. What (1 << client) does is tell it to take the number 1 and move it to the left client bits. So:

Code:
(1 << 0) = 0b00000001
(1 << 1) = 0b00000010
(1 << 2) = 0b00000100
and there are 32-bits to a cell in Pawn.

It's a cheap way of storing a bunch of bools as a single value.
__________________
Not currently working on SourceMod plugin development.

Last edited by Powerlord; 12-30-2013 at 16:52.
Powerlord is offline
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 15:27.


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