how to show name of player that you are pointing to

Please post any questions about developing your plugin here. Please use the search function before posting!
8guawong
Senior Member
Posts: 148
Joined: Sat Sep 20, 2014 3:06 am

how to show name of player that you are pointing to

Postby 8guawong » Sun Nov 23, 2014 11:24 pm

not sure how to do this..

an example
Attachments
2014-11-24_00001.jpg
User avatar
satoon101
Project Leader
Posts: 2703
Joined: Sat Jul 07, 2012 1:59 am

Postby satoon101 » Sun Nov 23, 2014 11:37 pm

mp_playerid should do this, but I don't know if that works in CS:GO.

Outside of that, this thread should give you a good idea:
http://forums.sourcepython.com/showthread.php?579
Image
User avatar
Ayuto
Project Leader
Posts: 2208
Joined: Sat Jul 07, 2012 8:17 am
Location: Germany

Postby Ayuto » Sun Nov 23, 2014 11:40 pm

User avatar
Ayuto
Project Leader
Posts: 2208
Joined: Sat Jul 07, 2012 8:17 am
Location: Germany

Postby Ayuto » Tue Nov 25, 2014 3:34 pm

Here is the code. Satoon will commit something similar to the entities_changes branch very soon.

Syntax: Select all

#  =============================================================================
# >> IMPORTS
# =============================================================================
# Python
import math

# Source.Python
from engines.trace import engine_trace
from engines.trace import Ray
from engines.trace import GameTrace
from engines.trace import TraceFilterSimple

from mathlib import Vector

from memory import Pointer

from events import Event

from players.entity import PlayerEntity
from players.helpers import index_from_userid

from entities.helpers import edict_from_index
from entities.helpers import index_from_pointer


# =============================================================================
# >> CONSTANTS
# =============================================================================
MAX_TRACE_LENGTH = 1.732050807569 * 2 * 16384


# =============================================================================
# >> FUNCTIONS
# =============================================================================
def get_view_entity(player):
"""Returns the entity that the player is looking at."""

# Get the eye location of the player
start_vec = get_eye_location(player)

# Calculate the greatest possible distance
end_vec = start_vec + get_view_vector(player) * MAX_TRACE_LENGTH

# Create a new trace object
trace = GameTrace()

# Start the trace
engine_trace.trace_ray(
Ray(start_vec, end_vec),
0x1, # This value doesn't matter. Our trace filter ignores it
TraceFilterSimple((player.index,)),
trace
)

if not trace.did_hit():
return None

# Get the entity that the trace hit
pointer = Pointer(trace.get_entity().get_base_entity())

# Get the index of the entity the trace hit
return index_from_pointer(pointer, False)

def get_view_player(player):
"""Returns the player that the player is looking at."""

index = get_view_entity(player)
if index is None:
return None

edict = edict_from_index(index)
return index if edict.get_class_name() == 'player' else None

def get_eye_location(player):
'''
Returns the eye location of the player.
'''

return Vector(*tuple(player.get_prop_float(
'm_vecViewOffset[{0}]'.format(x)) + y for x, y in \
enumerate(player.location)))

def get_view_vector(player):
'''
Returns the view vector of the player.
'''

eye_angle0 = player.get_prop_float('m_angEyeAngles[0]')
eye_angle1 = player.get_prop_float('m_angEyeAngles[1]')
return Vector(
math.cos(math.radians(eye_angle1)),
math.sin(math.radians(eye_angle1)),
-1 * math.sin(math.radians(eye_angle0))
)


# =============================================================================
# >> TEST
# =============================================================================
@Event
def player_say(event):
userid = event.get_int('userid')
index = index_from_userid(userid)
player = PlayerEntity(index)

index2 = get_view_player(player)
if index2 is None:
print('Not a player.')
else:
print(PlayerEntity(index2).name)
arawra
Senior Member
Posts: 190
Joined: Fri Jun 21, 2013 6:51 am

Postby arawra » Fri May 29, 2015 9:14 am

So I was just trying to use this script again, and got a lot of the kinks out with the updates. There is one traceback though I'm not sure how to work through because I'm not sure what values to pass to Pointer in memory module.

Syntax: Select all

pointer = Pointer(trace.get_entity().get_base_entity())


Code: Select all

Boost.Python.ArgumentError: Python argument types in
    Pointer.__init__(Pointer, BaseEntity)
did not match C++ signature:
    __init__(struct _object *, class CPointer {lvalue})
    __init__(struct _object *)
    __init__(struct _object *, unsigned long)
    __init__(struct _object *, unsigned long, bool)
User avatar
Ayuto
Project Leader
Posts: 2208
Joined: Sat Jul 07, 2012 8:17 am
Location: Germany

Postby Ayuto » Fri May 29, 2015 9:50 am

The error tells you which types you can pass to the constructor. However, you don't need the pointer thing. Just return trace.get_entity_index().
User avatar
satoon101
Project Leader
Posts: 2703
Joined: Sat Jul 07, 2012 1:59 am

Postby satoon101 » Fri May 29, 2015 11:46 am

Just so you know, we did already implement a get_view_entity method for PlayerEntity along with a view_player property:

Syntax: Select all

print(player.get_view_player().name)
print(player.view_player.name)


Of course, those 2 will return None if the player is not looking at another player. That will cause an AttributeError in the above, since None has no "name" attribute.
Image
User avatar
Mahi
Senior Member
Posts: 236
Joined: Wed Aug 29, 2012 8:39 pm
Location: Finland

Postby Mahi » Fri May 29, 2015 12:11 pm

satoon101 wrote:Just so you know, we did already implement a get_view_entity method for PlayerEntity along with a view_player property:

Syntax: Select all

print(player.get_view_player().name)
print(player.view_player.name)


Of course, those 2 will return None if the player is not looking at another player. That will cause an AttributeError in the above, since None has no "name" attribute.
Why the view_player property? Any difference between get_view_player()?

EDIT: Checked the code, literally the same methods. Is there a reason you have a support for get/set methods AND properties? Just curious :smile:
User avatar
satoon101
Project Leader
Posts: 2703
Joined: Sat Jul 07, 2012 1:59 am

Postby satoon101 » Fri May 29, 2015 12:44 pm

The property wraps the 2 methods. This is actually a fairly common practice. We use it quite a bit for Entity/PlayerEntity.
Image
User avatar
Mahi
Senior Member
Posts: 236
Joined: Wed Aug 29, 2012 8:39 pm
Location: Finland

Postby Mahi » Fri May 29, 2015 1:42 pm

satoon101 wrote:The property wraps the 2 methods. This is actually a fairly common practice. We use it quite a bit for Entity/PlayerEntity.

Never seen it before, I've only seen people use either properties (usually with the decorator) or set_x() and get_x() methods, but never both (doesn't mean it's wrong or anything, I just mentioned that I haven't seen it before :D ). But why have two ways to do the exact same thing? Seems to just cause confusion imo.

Edit: Usually the get and set methods would be marked "private" with an underscore, in which case they're meant to be used through the property only, but you seem to encourage people to use both the property AND the methods? I don't mean to be offensive here, but I just don't see the reason behind having two ways to do things.
User avatar
Ayuto
Project Leader
Posts: 2208
Joined: Sat Jul 07, 2012 8:17 am
Location: Germany

Postby Ayuto » Fri May 29, 2015 6:26 pm

We decided that we want to have properties, because we think they are more handy. Do you have any sources for the "usually" in your edit? I have never seen a proposal for that. Though, I should also mention that I didn't search for it.

If you are looking for other projects, which are using get_*/set_* and properties take a look at wxPython. It's quite big and it's also using both. It gives people the choice to use their preference. When I started using wxPython, it didn't confuse me at all.

Edit: Fixed the error. https://github.com/Source-Python-Dev-Team/Source.Python/commit/7fd6d466f25dd7d366ca8cc3115f3cfd23a6a296
User avatar
Mahi
Senior Member
Posts: 236
Joined: Wed Aug 29, 2012 8:39 pm
Location: Finland

Postby Mahi » Fri May 29, 2015 7:07 pm

Ayuto wrote:We decided that we want to have properties, because we think they are more handy.
I completely agree with you. Which is why I'd just go with the "newest" version of using properties, instead of having set and get methods separately. Example:

Syntax: Select all

class Example: 
@property
def x(self):
return self._x

@x.setter
def x(self, value):
self._x = value


Ayuto wrote:Do you have any sources for the "usually" in your edit?
Flask, Django, scrapy, etc... Not too many use the wxPython way as far as I'm aware. At least not too many "big" projects.

Basically what I'm saying is you should have ONE way of doing things, not two.

I'd recommend one of these:

Syntax: Select all

#
# Only properties (I personally prefer this)
#
@property
def x(self):
return self._x

@x.setter
def x(self, value):
self._x = value

#
# Only get() and set() methods:
#
def get_x(self):
return self._x

def set_x(self, value):
self._x = value

#
# _get(), _set() and property()
#
def _get_x(self):
return self._x

def _set_x(self, value):
self._x = value

x = property(_get_x, _set_x)

Basically I can't see any reason to go with the third method instead of the first one, other than making property overriding just a tiny bit easier. It's still possible with the first method too.

The second method is just if you prefer get() and set() over properties, but I don't know too many people who do (not saying there aren't any, I just don't know too many), but I also don't think it's a good idea to let everyone have it their way instead of everyone using the same rules and same code.
User avatar
satoon101
Project Leader
Posts: 2703
Joined: Sat Jul 07, 2012 1:59 am

Postby satoon101 » Fri May 29, 2015 7:27 pm

I really don't see what's inherently wrong with how we already have it. I have seen plenty of other projects that use the same implementation as us. I am still a little shocked over your statement that you have "never seen this before". I know some people prefer to use methods while others prefer to use properties. How is it so 'confusing' when you can use either?
Image
User avatar
Ayuto
Project Leader
Posts: 2208
Joined: Sat Jul 07, 2012 8:17 am
Location: Germany

Postby Ayuto » Fri May 29, 2015 7:45 pm

I just read about properties and found a quote of the zen of python, which is obviously a point for you.
There should be one-- and preferably only one --obvious way to do it.
And since we are actually following many proposals, we should think about following that as well.
User avatar
satoon101
Project Leader
Posts: 2703
Joined: Sat Jul 07, 2012 1:59 am

Postby satoon101 » Fri May 29, 2015 8:11 pm

Well, I don't think that fully applies in this instance as, in my view, that is for not creating 2 separate and distinct ways of doing the same thing. If we were to fully follow that rule as if it applied fully universally, one could argue that using the Entity/PlayerEntity attributes we add dynamically is creating a second way to get/set networked properties.

However, having said that, if we want to move in that direction in this instance, I am alright with it. I do think that the first option Mahi mentions above looks very tacky. I would actually prefer handling them much like the properties in the memory.manager package.
Image
User avatar
Mahi
Senior Member
Posts: 236
Joined: Wed Aug 29, 2012 8:39 pm
Location: Finland

Postby Mahi » Fri May 29, 2015 8:57 pm

satoon101 wrote:Well, I don't think that fully applies in this instance as, in my view, that is for not creating 2 separate and distinct ways of doing the same thing. If we were to fully follow that rule as if it applied fully universally, one could argue that using the Entity/PlayerEntity attributes we add dynamically is creating a second way to get/set networked properties.

However, having said that, if we want to move in that direction in this instance, I am alright with it. I do think that the first option Mahi mentions above looks very tacky. I would actually prefer handling them much like the properties in the memory.manager package.

I don't know about the Entity/PlayerEntity thing, but imo this is exactly what the zen says. And I don't really have anything other than the zen Ayuto pasted to back me up here, but that's how I've learnt Python and that's how I think it should be done. There should be only one way to access player's attributes (preferrably through properties), not two. But that's a decision left for you guys to make, I'm just giving out my opinion :)

And what do you mean by "tacky"? It's the shortest way, and as far as I'm aware, it's the "recommended" way in Python 3. It's simple, unmistakable and easy to understand.
Python 3's properties are the best ones I've ever used (along with C#'s properties) due to the @property and @property.setter decorators, they're insanely easy to code with :)
User avatar
satoon101
Project Leader
Posts: 2703
Joined: Sat Jul 07, 2012 1:59 am

Postby satoon101 » Mon Jun 01, 2015 1:00 pm

Maybe tacky isn't the right word. I just don't like how the getter and setter are declared differently. It doesn't sit well with me. My biggest issue, though, is documentation. For instance:

Syntax: Select all

>>> class Test(object):

@property
def origin(self):
"""Return the origin."""
return None

@origin.setter
def origin(self, value):
"""Set the origin."""
pass


>>> help(Test.origin)
Help on property:

Return the origin.


Versus:

Syntax: Select all

>>> class Test(object):

def _get_origin(self):
"""Return the origin."""
return None

def _set_origin(self, value):
"""Set the origin."""
pass

origin = property(_get_origin, _set_origin, doc="""Property that stores the origin of the object.""")


>>> help(Test.origin)
Help on property:

Property that stores the origin of the object.



Now, we also could do the following:

Syntax: Select all

>>> class Test(object):

origin = property(doc="""Property that stores the origin of the object.""")

@origin.getter
def origin(self):
"""Return the origin."""
return None

@origin.setter
def origin(self):
"""Set the origin."""
pass


>>> help(Test.origin)
Help on property:

Property that stores the origin of the object.



Having said all of that, we actually have one instance in which we currently have to allow methods. With <Entity>.set_color, we have a second argument that allows a scripter to use the entity's current alpha value, so as not to change the alpha in case another script is handling that. We 'could' remove this second argument and just make sure scripters know to get the entity's alpha value themselves when setting the color:

Syntax: Select all

entity.color = Color(255, 0, 0, entity.color.a)



As far as the Entity properties I mentioned, this is what I mean:

Syntax: Select all

player = PlayerEntity(1)

# Get the player's kills using attributes
kills = player.kills

# Set the player's kills using attributes
player.kills = 20

# Get the player's kills using get_property_<type>
kills = player.get_property_int('m_iFrags')

# Set the player's kills using set_property_<type>
player.set_property_int('m_iFrags', 20)



There are actually a number of things in which there are a couple ways to do them. I don't think this is such a huge issue as this thread is making it out to be.
Image
User avatar
BackRaw
Senior Member
Posts: 537
Joined: Sun Jul 15, 2012 1:46 am
Location: Germany
Contact:

Postby BackRaw » Mon Jun 01, 2015 5:59 pm

IMO the way properties are defined in SP are awesome. Please don't change it :D
My Github repositories:

Source.Python: https://github.com/backraw
User avatar
Mahi
Senior Member
Posts: 236
Joined: Wed Aug 29, 2012 8:39 pm
Location: Finland

Postby Mahi » Mon Jun 01, 2015 9:57 pm

I don't mean to be rude at any point of this answer, I'm just trying to say what I think about all this, and I like being kind of "offensive" (making my points clear :grin: ) when trying to prove my point. That being said, here's my personal opinion on this stuff, with some sort of arguments to base my opinions on:

Documentation
1. Do you have docstrings on your attributes? If not, why do you need them on properties?
They're almost equal and you can't tell the difference anyways: Is person.name an attribute or a property? Do you need docstrings to know what it does? What about player.kills or player.color?

2. Say you really need the documentation on a property. When setting a color, maybe it isn't obvious if you're supposed to use hex-codes or instances of the Color class. Isn't it enough to documentate the property? How often do you actually access the docstrings of the fget and fset?

Syntax: Select all

help(Test.origin.fset)
I'd say never, as it should always be enough to access the docstring of the property itself.

If this is the case, you're good to go with @property, as the getter's docstring is automatically the property's docstring. Here's a good answer about docstrings and properties on stackoverflow.com

Color property
1. This one never made sense to me in the first place (when you pushed the update), why would you have a parameter to keep the alpha? Sure, it makes things just a bit easier, but it's not like keeping the alpha is too hard (as you've shown in your example), and the parameter for set_color() doesn't really make things that much easier.
I think it should be the programmer's responsibility to get their colors right: alpha is a part of the color and that's how it should be treated. You don't have parameters to keep red, green or blue values either. If you're changing an object's color (instance of the Color class) to an other color which has a different alpha value, obviously the object's color's alpha value should change.

2. If you ever have an attribute that needs extra parameters (I don't think color needs them) and you literally can't make it a property, maybe it shouldn't be a property. That's exactly when you use a normal method, that's not what properties are for. So that's for that I guess, if you need a parameter for a property, that's not really too much of a property.

3. I thought you guys wanted to keep SP uniform with the source engine, I highly doubt there's a bool keepAlphaValueButChangeAllOtherValues=true argument in there? ;)

Entity properties
What comes to your last example (setting the kills in "two different ways"), that's basically what properties are for. You have one way of doing something, and you make it easier by turning it into a property (that's what functions overall are for).
In your example, you get kills by calling player.get_property_int('m_iFrags'). It gets kind of hard to remember all the strings and whether some values are ints or bools, and it just makes perfect sense to shorten this to use a property.

My argumentation skills are rather low to prove my point here, so I'll just go with an example.
Do you think this is two ways of doing the same thing:

Syntax: Select all

# Method one (not CS:GO or SP example, just some random game)
player._health -= 100
if player._health <= 0:
player._health = 0
player.events['death'].signal(target=player)

# Method two
player.health -= 100
They do the EXACT same thing (literally same code), both reduce player's health and then send a signal about player dying if he died, but I wouldn't call that "a couple of ways to do things". That's exactly what properties (and functions overall) are for, you take a piece of code that's hard to remember or somewhat complicated and often used, and you pack it up.

So player.kills is just packing up the harder-to-remember and longer command which needs to access some player's property strings (very unpythonic overall) into a property. That's not really two ways of doing the same thing, if you understand what I mean.

Property vs get & set
I'm referring to the "Entity properties" section of this answer and the Python example about signaling player's death:
When we have a complicated way of doing something, for example setting player's health and checking if he dies, we can turn it into a function or a property (Health is a property, so we'll turn it into a property. Connecting to a database should be a function, killing a player (by other means than changing health) should be a function. Setting a health shouldn't be a function, it should be a property.)

Now that we've done the "packing up complicated code" and we have an easy way of setting player's health and signaling his death, everyone will always use the health property instead of always rewriting the four lines of code that's packed inside the property's setter. This is good, we've made a function to make life easier.

Now introducing: get_health() and set_health()!! An other way to pack a complicated command into a simple command, that's no different from the previous way of doing the exact same thing (via property) and people don't know whether to use the property or these two new methods! Congratulations, you didn't do anything new, you're just introducing a second way of doing the exact same thing: packing up the code and executing it easier.

Sorry for the wall of text, and sorry if it feels like some of my sentences are a bit offensive, but I don't know how to phrase my arguments better. I do feel like this gets my point clear tho, and surely I might be wrong about something, but at least you now know my opinion and why I think you're simply wrong and I'm right.

EDIT: Also your comment "I don't think this is such a huge issue as this thread is making it out to be" is surely true, but it sounds like you think we should just ignore this because it's not a big issue. Maybe we should, or maybe I understood your comment incorrectly, but I think SP should use properties, regardless of how huge of an issue it is! :)
User avatar
BackRaw
Senior Member
Posts: 537
Joined: Sun Jul 15, 2012 1:46 am
Location: Germany
Contact:

Postby BackRaw » Tue Jun 02, 2015 12:45 am

You simply have two methods, get & set, plus a property that makes accessing these easier (but does the same thing). I think the .setter stuff would make code less readable. Don't know about the alpha parameter tho.

Mahi wrote:Now introducing: get_health() and set_health()!! An other way to pack a complicated command into a simple command, that's no different from the previous way of doing the exact same thing (via property) and people don't know whether to use the property or these two new methods! Congratulations, you didn't do anything new, you're just introducing a second way of doing the exact same thing: packing up the code and executing it easier.


What's so wrong about having two methods and then a wrapper for both of them as a property? You said it yourself, you can do things this or that way. SP lets scripters use which they want (set&get or property). I think the work done is very pythonic and quality work.

The code is
  • readable
  • easy to understand (informative docstrings)
  • structured
  • extensible via .ini files (easy way to create better support for more games)

For the last of my points:
Mahi wrote:So player.kills is just packing up the harder-to-remember and longer command which needs to access some player's property strings (very unpythonic overall) into a property. That's not really two ways of doing the same thing, if you understand what I mean.
The property is defined in the respective .ini file, the Enity/PlayerEntity class basically looks for these entity properties (like kills) in the file and maps them to their respective values (like m_iFrags) using python properties, thus creating an easy way to read and change the value.

What's wrong with letting SP do the hard work and letting players use what Satoon mentioned here?
satoon101 wrote:

Syntax: Select all

player = PlayerEntity(1)

# Get the player's kills using attributes
kills = player.kills

# Set the player's kills using attributes
player.kills = 20

# Get the player's kills using get_property_<type>
kills = player.get_property_int('m_iFrags')

# Set the player's kills using set_property_<type>
player.set_property_int('m_iFrags', 20)
My Github repositories:

Source.Python: https://github.com/backraw

Return to “Plugin Development Support”

Who is online

Users browsing this forum: No registered users and 61 guests