how to show name of player that you are pointing to
Posted: Sun Nov 23, 2014 11:24 pm
not sure how to do this..
an example
an example
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)
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)
Syntax: Select all
print(player.get_view_player().name)
print(player.view_player.name)
Why the view_player property? Any difference between get_view_player()?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.
satoon101 wrote:The property wraps the 2 methods. This is actually a fairly common practice. We use it quite a bit for Entity/PlayerEntity.
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:Ayuto wrote:We decided that we want to have properties, because we think they are more handy.
Syntax: Select all
class Example:
@property
def x(self):
return self._x
@x.setter
def x(self, value):
self._x = value
Flask, Django, scrapy, etc... Not too many use the wxPython way as far as I'm aware. At least not too many "big" projects.Ayuto wrote:Do you have any sources for the "usually" in your edit?
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)
And since we are actually following many proposals, we should think about following that as well.There should be one-- and preferably only one --obvious way to do it.
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.
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.
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.
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.
Syntax: Select all
entity.color = Color(255, 0, 0, entity.color.a)
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)
Syntax: Select all
help(Test.origin.fset)
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
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.
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.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.
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)