PDA

View Full Version : TF2 Sprite


Skippy
11-11-2014, 12:06
So I have sprite above players heads and right now I have it teleporting every game frame but it's very choppy and doesn't look smooth. Is OnGameFrame the only way to have it follow the player around? (Keep in mind this is for TF2)

Michalplyoutube
11-11-2014, 12:22
So I have sprite above players heads and right now I have it teleporting every game frame but it's very choppy and doesn't look smooth. Is OnGameFrame the only way to have it follow the player around? (Keep in mind this is for TF2)

Well attach it instead of teleporting to hat or head

Skippy
11-11-2014, 12:36
Well attach it instead of teleporting to hat or head

As far as I know TF2 doesn't allow attachments and if it's able to attach could you show me?

Plaffy46
11-12-2014, 06:14
I found some stock functionsin zombie fortress doing that, I don't know if this method still works though, anyways, here you go :

stock fxCreateSprite(
const String:strSprite[],
target,
&entSpr,
&entAnc)
{
//
// Create a networked sprite attached to a player's head.
// This is done by parenting a sprite to a false 'anchor' prop, and then
// parenting the anchor to a target. While the anchor will not be visible,
// the sprite will be. Furthermore, since the sprite is parented to a
// networked entity, an extension like SDKHooks can be used to selectively
// display the sprite to an arbitrary set of clients.
//
entSpr = CreateEntityByName("env_sprite");
if(IsValidEntity(entSpr))
{
entAnc = CreateEntityByName("prop_physics_multiplayer");
if(IsValidEntity(entAnc))
{
decl String:strSprTargetname[32];
decl String:strAncTargetname[32];
decl String:strTgtTargetname[32];
Format(strSprTargetname, sizeof(strSprTargetname), "zfspr%i", entSpr);
Format(strAncTargetname, sizeof(strAncTargetname), "zfanc%i", entAnc);
Format(strTgtTargetname, sizeof(strTgtTargetname), "zftgt%i", target);

// Retrieve target's position
decl Float:posTgt[3];
GetEntPropVector(target, Prop_Send, "m_vecOrigin", posTgt);
posTgt[2] += 12.0;

// Configure target.
DispatchKeyValue(target, "targetname", strTgtTargetname);

// Configure and spawn anchor.
DispatchKeyValue(entAnc, "targetname", strAncTargetname);
DispatchKeyValue(entAnc, "parentname", strTgtTargetname);
SetEntityMoveType(entAnc, MOVETYPE_NOCLIP);
SetEntityModel(entAnc, ZFMDL_PRESENT[0]);
SetEntityRenderMode(entAnc, RENDER_TRANSCOLOR);
SetEntityRenderColor(entAnc, 0, 0, 0, 0);
DispatchSpawn(entAnc);

// Configure and spawn sprite.
DispatchKeyValue(entSpr, "targetname", strSprTargetname);
DispatchKeyValue(entSpr, "parentname", strAncTargetname);
DispatchKeyValue(entSpr, "model", strSprite);
DispatchKeyValue(entSpr, "classname", "env_sprite");
DispatchKeyValue(entSpr, "spawnflags", "1");
DispatchKeyValue(entSpr, "scale", "0.1");
DispatchKeyValue(entSpr, "rendermode", "1");
DispatchKeyValue(entSpr, "rendercolor", "255 255 255");
DispatchSpawn(entSpr);

// Teleport sprite and anchor to target.
TeleportEntity(entSpr, posTgt, NULL_VECTOR, NULL_VECTOR);
TeleportEntity(entAnc, posTgt, NULL_VECTOR, NULL_VECTOR);

// Parent sprite to anchor.
SetVariantString(strAncTargetname);
AcceptEntityInput(entSpr, "SetParent", entSpr, entSpr, 0);

// Parent anchor to target.
AcceptEntityInput(entAnc, "DisableMotion");
AcceptEntityInput(entAnc, "DisableShadow");
SetVariantString(strTgtTargetname);
AcceptEntityInput(entAnc, "SetParent", entAnc, entAnc, 0);
SetVariantString("head");
AcceptEntityInput(entAnc, "SetParentAttachmentMaintainOffset", entAnc, entAnc, 0);
}
else
{
LogError("[ZF] fxCreateSprite(entAnc) (%s, %d) failed.", strSprite, target);
}
}
else
{
LogError("[ZF] fxCreateSprite(entSpr) (%s, %d) failed.", strSprite, target);
}
}

stock fxDeleteSprite(entSpr, entAnc)
{
if(fxIsSpriteValid(entSpr, entAnc))
{
AcceptEntityInput(entSpr, "Kill");
AcceptEntityInput(entAnc, "Kill");
}
}

stock fxShowSprite(entSpr, entAnc)
{
if(fxIsSpriteValid(entSpr, entAnc))
AcceptEntityInput(entSpr, "ShowSprite");
}

stock fxHideSprite(entSpr, entAnc)
{
if(fxIsSpriteValid(entSpr, entAnc))
AcceptEntityInput(entSpr, "HideSprite");
}

Skippy
11-12-2014, 20:12
Yeah every time I'm trying to use this coding it's crashing the server now

404UserNotFound
11-12-2014, 20:43
From "[TF2] Donator Recognition (https://forums.alliedmods.net/showthread.php?p=1128547)":

new g_EntList[MAXPLAYERS + 1];

stock CreateSprite(client, String:sprite[], Float:offset)
{
new String:szTemp[64];
Format(szTemp, sizeof(szTemp), "client%i", client);
DispatchKeyValue(client, "targetname", szTemp);

new Float:vOrigin[3];
GetClientAbsOrigin(client, vOrigin);
vOrigin[2] += offset;
new ent = CreateEntityByName("env_sprite_oriented");
if (ent)
{
DispatchKeyValue(ent, "model", sprite);
DispatchKeyValue(ent, "classname", "env_sprite_oriented");
DispatchKeyValue(ent, "spawnflags", "1");
DispatchKeyValue(ent, "scale", "0.1");
DispatchKeyValue(ent, "rendermode", "1");
DispatchKeyValue(ent, "rendercolor", "255 255 255");
DispatchKeyValue(ent, "targetname", "donator_spr");
DispatchKeyValue(ent, "parentname", szTemp);
DispatchSpawn(ent);

TeleportEntity(ent, vOrigin, NULL_VECTOR, NULL_VECTOR);

g_EntList[client] = ent;
}
}

stock KillSprite(client)
{
if (g_EntList[client] > 0 && IsValidEntity(g_EntList[client]))
{
AcceptEntityInput(g_EntList[client], "kill");
g_EntList[client] = 0;
}
}

public OnGameFrame()
{
if (!g_bRoundEnded) return;
new ent, Float:vOrigin[3], Float:vVelocity[3];

for(new i = 1; i <= MaxClients; i++)
{
if (!IsClientInGame(i)) continue;
if ((ent = g_EntList[i]) > 0)
{
if (!IsValidEntity(ent))
g_EntList[i] = 0;
else
if ((ent = EntRefToEntIndex(ent)) > 0)
{
GetClientEyePosition(i, vOrigin);
vOrigin[2] += 25.0;
GetEntDataVector(i, gVelocityOffset, vVelocity);
TeleportEntity(ent, vOrigin, NULL_VECTOR, vVelocity);
}
}
}
}

Use "CreateSprite(i, "%.vmt", 25.0);", where "%" is the name of the sprite VMT (and the path to it, I believe). "25.0" is the offset which I believe would be the height.

Use "KillSprite(i);" to kill it.

I'm actually picking up an old project that I put to the side for a while, which is to re-code the Donator Recognition plugin so it doesn't require use of the Basic Donator Interface plugin.

Skippy
11-13-2014, 09:24
From "[TF2] Donator Recognition (https://forums.alliedmods.net/showthread.php?p=1128547)":

new g_EntList[MAXPLAYERS + 1];

stock CreateSprite(client, String:sprite[], Float:offset)
{
new String:szTemp[64];
Format(szTemp, sizeof(szTemp), "client%i", client);
DispatchKeyValue(client, "targetname", szTemp);

new Float:vOrigin[3];
GetClientAbsOrigin(client, vOrigin);
vOrigin[2] += offset;
new ent = CreateEntityByName("env_sprite_oriented");
if (ent)
{
DispatchKeyValue(ent, "model", sprite);
DispatchKeyValue(ent, "classname", "env_sprite_oriented");
DispatchKeyValue(ent, "spawnflags", "1");
DispatchKeyValue(ent, "scale", "0.1");
DispatchKeyValue(ent, "rendermode", "1");
DispatchKeyValue(ent, "rendercolor", "255 255 255");
DispatchKeyValue(ent, "targetname", "donator_spr");
DispatchKeyValue(ent, "parentname", szTemp);
DispatchSpawn(ent);

TeleportEntity(ent, vOrigin, NULL_VECTOR, NULL_VECTOR);

g_EntList[client] = ent;
}
}

stock KillSprite(client)
{
if (g_EntList[client] > 0 && IsValidEntity(g_EntList[client]))
{
AcceptEntityInput(g_EntList[client], "kill");
g_EntList[client] = 0;
}
}

public OnGameFrame()
{
if (!g_bRoundEnded) return;
new ent, Float:vOrigin[3], Float:vVelocity[3];

for(new i = 1; i <= MaxClients; i++)
{
if (!IsClientInGame(i)) continue;
if ((ent = g_EntList[i]) > 0)
{
if (!IsValidEntity(ent))
g_EntList[i] = 0;
else
if ((ent = EntRefToEntIndex(ent)) > 0)
{
GetClientEyePosition(i, vOrigin);
vOrigin[2] += 25.0;
GetEntDataVector(i, gVelocityOffset, vVelocity);
TeleportEntity(ent, vOrigin, NULL_VECTOR, vVelocity);
}
}
}
}

Use "CreateSprite(i, "%.vmt", 25.0);", where "%" is the name of the sprite VMT (and the path to it, I believe). "25.0" is the offset which I believe would be the height.

Use "KillSprite(i);" to kill it.

I'm actually picking up an old project that I put to the side for a while, which is to re-code the Donator Recognition plugin so it doesn't require use of the Basic Donator Interface plugin.

Yeah I already use that coding. It teleports it on game frame which I don't want. It's not smooth.

404UserNotFound
11-16-2014, 20:31
Look for Noodleboy 347's old Premium mod (someone recently re-did and re-released it), that has a CreateParticle function in it with a few attachment points (head, back). I'm pretty sure you can mess with that and make it use sprite entities instead of particles.

Drixevel
11-16-2014, 23:08
You could also try OnPostThink or OnPreThink as well from SDKHooks to update the location of the sprite.

Skippy
11-16-2014, 23:40
You could also try OnPostThink or OnPreThink as well from SDKHooks to update the location of the sprite.

Wouldn't that result in the same thing as OnGameFrame?

404UserNotFound
11-17-2014, 00:49
Why not somehow convert the sprite into a particle and use the CreateParticle thingy?

I know there's a custom particle plugin on here somewhere...

Drixevel
11-17-2014, 01:09
Wouldn't that result in the same thing as OnGameFrame?

When I was running some tests on a test server between OnGameFrame & OnPostThink/OnPreThink, the SDKHooks seem to run a bit smoother.

The only solid way you can do this seamlessly would be to update server/client lerp, create a particle and have it just hover above player's heads OR figure out a way to use an attachment to clients for sprite entities.

Plaffy46
11-17-2014, 14:31
Well, I'm pretty sure the code used in zombie fortress besides some eventual updates and changes should work.

I often go on a server running this plugin, and zombies still have the particle effect attached to their head, and it's smooth. Check by yourself, the IP is 185.16.84.180:27045, when on the server, go zombie select "Rage" as perk for example and call for medic, then look at the flames on your head and try moving (the best way is probably conga to move while staying in thirdperson, i guess).

If it works for particles, there are no reason this shouldn't work for sprites right?

Skippy
11-17-2014, 21:08
I'm spawning the sprite just fine but the second I add this coding
SetVariantString(szTemp);
AcceptEntityInput(ent, "SetParent", iClient, ent);

It doesn't show up anymore

Skippy
11-19-2014, 19:39
Any help with the above post?

404UserNotFound
11-19-2014, 20:03
Any help with the above post?

Gonna need more code than that to help figure out what's going on.

Skippy
11-19-2014, 20:27
Gonna need more code than that to help figure out what's going on.


stock CreateSprite(iClient, String:sprite[], Float:offset)
{

new String:szTemp[64];
GetClientName(iClient, szTemp, sizeof(szTemp));

new Float:vOrigin[3];
GetClientAbsOrigin(iClient, vOrigin);
vOrigin[2] += offset;
new ent = CreateEntityByName("env_sprite_oriented");
new String:sprite_name[128];
Format(sprite_name, sizeof(sprite_name), "Sprite%i", ent);
if (ent)
{
DispatchKeyValue(ent, "model", sprite);
DispatchKeyValue(ent, "classname", "env_sprite_oriented");
DispatchKeyValue(ent, "spawnflags", "1");
DispatchKeyValue(ent, "scale", "0.1");
DispatchKeyValue(ent, "rendermode", "1");
DispatchKeyValue(ent, "rendercolor", "255 255 255");
DispatchKeyValue(ent, "targetname", sprite_name);
DispatchKeyValue(ent, "parentname", szTemp);
DispatchSpawn(ent);

TeleportEntity(ent, vOrigin, NULL_VECTOR, NULL_VECTOR);

g_EntList[iClient] = ent;

SetVariantString(szTemp);
AcceptEntityInput(ent, "SetParent", iClient, ent);
}
}

Chdata
11-20-2014, 04:24
Try moving teleportentity before you set the parentname

That might not be it though...

Oshizu
11-20-2014, 08:01
Try perhaps using two sprites instead one
1st attached to player
2nd attached to sprite that was attached to player before?

friagram
11-21-2014, 03:16
Let's not try to attach stuff to players when it's actively being disabled by design.

Use a different method. Entities such as env_spritetrail, info_particle_system will display properly when attached to players.

Skippy
11-21-2014, 17:06
Let's not try to attach stuff to players when it's actively being disabled by design.

Use a different method. Entities such as env_spritetrail, info_particle_system will display properly when attached to players.

The sprite trail repeats the image over and over and a particle system won't be an image :cry: so how would I use any of those?

friagram
11-22-2014, 17:10
Hmm, it's been a while but iirc tf2 has some tempents that you CAN parent to players and do a bunch of stuff with, you'll have to look through the dumps, but there's particle, physprop, and a few others, might be some sprite based ones.

Skippy
11-22-2014, 18:43
Hmm, it's been a while but iirc tf2 has some tempents that you CAN parent to players and do a bunch of stuff with, you'll have to look through the dumps, but there's particle, physprop, and a few others, might be some sprite based ones.

Yeah I don't know what this dump is and I don't know where to look.