PDA

View Full Version : Get Entity Key Value?


Spirrwell
11-08-2014, 17:39
Hi there! I've looked this up and all I've seen is about getting entity properties, not an entity key value directly. I know you can instill key values with DispatchKeyValue(), but there is no way to actually get a key value.

Basically I've been learning about creating my own custom gamemode and I wanted to do it in a "proper" kind of way. By editing and creating an FGD file for Hammer to create an entity. One of the key values I added was:

FlagCaptureLimit(integer) : "Capture Limit" : 10 : "Captures needed to win."

It shows up perfectly fine in Hammer. So, how would I go about getting the "FlagCaptureLimit" value from SourcePawn? Is it just not possible?

Powerlord
11-08-2014, 19:51
Values you dispatch with DispatchKeyValues correspond to DataMap values.

Look it up in an sm_datamap_dump.

bl4nk
11-08-2014, 21:04
He means:
sm_dump_datamaps <file>

:>

Spirrwell
11-08-2014, 21:14
He means:
sm_dump_datamaps <file>

:>

Thanks, that worked, but what exactly am I looking for in this file? I don't understand. It's not like I edited the source code to the mod or anything, I just modified the FGD file. How does this work then?

friagram
11-08-2014, 22:09
Fgd values are usually on the right, you would see like m_iHealth Health, or m_Hdamage Damage, or whatever. Those you could dispatch keyvalues as since you have their names. Else use the setent natives.

Spirrwell
11-08-2014, 22:59
I'm sorry, but maybe I made it a bit confusing by mentioning DispatchKeyValue(), but I'm NOT trying to set a key value.

Besides, FlagCaptureLimit in the FGD file I edited does not exist in the game's code, period. It's ONLY in the FGD file. So I'm not understanding all of this dumping stuff. I just want to get the key value, not set, get.

I created a test map with the entities I created\modified in the FGD files of this particular game. All I want is something that looks like this (pseudo-code):

new iFlagCaptures
new iEnt;
iEnt = FindEntityByClassName(iEnt, "info_pvk");
iFlagCaptures = GetKeyValue(iEnt, "FlagCaptureLimit");

Is there any way to get a key value directly?

Powerlord
11-09-2014, 02:54
I'm sorry, but maybe I made it a bit confusing by mentioning DispatchKeyValue(), but I'm NOT trying to set a key value.

Besides, FlagCaptureLimit in the FGD file I edited does not exist in the game's code, period. It's ONLY in the FGD file. So I'm not understanding all of this dumping stuff. I just want to get the key value, not set, get.

I created a test map with the entities I created\modified in the FGD files of this particular game. All I want is something that looks like this (pseudo-code):

new iFlagCaptures
new iEnt;
iEnt = FindEntityByClassName(iEnt, "info_pvk");
iFlagCaptures = GetKeyValue(iEnt, "FlagCaptureLimit");

Is there any way to get a key value directly?

I'm surprised that even works. Datamaps, Netprops, and KeyValues represent server-side variables compiled into the server binary (server.dll, server.so / server_srv.so, or server.dylib).

Just adding new properties to them in the map editor isn't going to magically pop those properties into being on the server side... the server is likely just going to toss them out (assuming it doesn't outright crash when the map is loaded).

friagram
11-09-2014, 11:20
You can add as many keyvalues to an entity as you like, they eill just do nothing.
Probably you could make an extension to read them or something...

Spirrwell
11-09-2014, 12:15
Oh cool, I've been looking for an excuse to try out extension programming. I find C++ much more understandable anyhow. However it does seem that trying to create NEW entities is futile. It looks like they really do get thrown out by the server. But anything I simply add key values to seems to work just fine there's just nothing to read it.

Thank you though, if I have to I'll use info_targets, and used a voting system to vote on the capture limit and whatnot, but I'll see what I can learn.

Thanks again! If I do happen to make any progress at all I'll post it here.

Powerlord
11-09-2014, 12:44
What game is this for, anyway?

I know in TF2, there's a server cvar that sets the number of caps in a round.

I was going to say that there must be a way to override the cap limit in TF2 as well because sd_doomsday requires just one, but it occurred to me (having not looked at a decompile of it) that they may just use a game_round_win entity to do that.

psychonic
11-09-2014, 13:49
I don't know much about mapping, and maybe they can store custom keys/values for use only in the map's own logic. Those indeed wouldn't show in a datamap dump. Additionally, not all compiled-in keys are mapped directly to variables and thus, would also not show up. The GetKeyValue/[Set]KeyValue baseentity functions special-cases many key names (as derived entities can also do).

You don't need an extension to call GetKeyValue. A BaseEntity SDKCall in an SM plugin would work fine.

This could also easily be added to SM itself as well if someone wants to do a Pull Request. GetKeyValue is exposed on the IServerTools interface, not requiring gamedata.

friagram
11-10-2014, 00:54
You can create any keyvalue you like in hammer by disabling the smart editor.
Possibly with addoutput, entities could make them as well, or at least set them? I did not try.
I never bothered to look and see if they are actually accessable in game. I know that entity classnames that are invalid get filtered out, and most datamap values that aren't used by the entity get reset/zeroed out pretty often (every frame?).

Powerlord
11-10-2014, 11:59
I don't know much about mapping, and maybe they can store custom keys/values for use only in the map's own logic.

You can create any keyvalue you like in hammer by disabling the smart editor.
Possibly with addoutput, entities could make them as well, or at least set them? I did not try.
I never bothered to look and see if they are actually accessable in game. I know that entity classnames that are invalid get filtered out, and most datamap values that aren't used by the entity get reset/zeroed out pretty often (every frame?).

I'll be totally honest here and say I haven't tried it.

However, glancing at the Source SDK code, the things that appear in the Hammer editor have backing fields in the class linked to the entity. They (and DataMaps) appear to be created using macros to link them to (already existing) backing fields. (Netprops have something similar, but the backing variables are declared as being a netprop on creation)

The point being that they work because they already have storage in the C++ code.

friagram
11-11-2014, 03:41
Yes, and when you check for errors it'll cry if the entity doesn't "support" that keyvalue...
Though sometimes it does... Common one is like angles on keyframe_rope, or hammerid on entities from decompiled maps, obviously hammerid and angles are valid. It likely only supports the values that are coded to work there :3

Spirrwell
11-12-2014, 03:50
Ah, the game I'm working with is Pirates, Vikings, and Knights II. I was hoping that I could make the gamemode feel less artificial (yeah, that word kind of makes no sense in this context anyway) by avoiding a reliance on SM menus and the like.

I looked at the code myself as well:

for ( datamap_t *dmap = GetDataDescMap(); dmap != NULL; dmap = dmap->baseMap )
{
if ( ::ExtractKeyvalue( this, dmap->dataDesc, dmap->dataNumFields, szKeyName, szValue, iMaxLen ) )
return true;
}
#endif

return false;


It doesn't seem possible. Oh well. I learned a lot about finding virtual offsets and whatnot thanks to this, so at least I learned something.