Page 1 of 1

CSGO: strict weapon

Posted: Tue Mar 31, 2015 5:57 am
by nullable
The next code stopped work property after update new version of sourcepython. Please help me to fix it. The idea is to strict knife weapon only.

Syntax: Select all

from entities.helpers import remove_entity
from events import Event
from entities.entity import BaseEntity
from filters.players import PlayerIter
from contextlib import suppress

@Event
def round_start(game_event):
for player in PlayerIter(return_types='player'):
with suppress(ValueError):
player.cash = 0
for weapon_index in player.weapon_indexes(not_filters='knife'):
weapon = BaseEntity(weapon_index)

# set its hammerid to its index (CS:GO crash fix)
weapon.set_key_value_int("hammerid", weapon.index)

player.drop_weapon(weapon.pointer, True, True)
remove_entity(weapon.index)

Posted: Tue Mar 31, 2015 7:39 pm
by nullable
Is any ideas how to fix it in new version?

Posted: Tue Mar 31, 2015 8:02 pm
by Ayuto
I guess with "property" you mean "properly". But can you describe your problem a little bit better? Do you get errors?

Posted: Tue Mar 31, 2015 9:36 pm
by Predz
Just started playing with this myself, and it seems to me that the "weapon_indexes" method is not returning anything at the moment. All I get is a empty list returned.

Posted: Tue Mar 31, 2015 9:58 pm
by Predz
Also, the "drop_weapon" virtual function uses the arguments of "POINTER, POINTER, POINTER" so therefore parse, "<pointer>, None, None" instead.

Posted: Tue Mar 31, 2015 10:01 pm
by Predz
This works for me, does what I think you wanted it to.

Syntax: Select all

##
##
##

from entities.helpers import index_from_pointer
from entities.helpers import index_from_edict

from events import Event

from filters.players import PlayerIter
from filters.entities import EntityIter

from memory.hooks import PreHook

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

from weapons.entity import WeaponEntity

##
##
##

bot_name = 'PreHook Bot'

restrictions = {}

##
##
##

for player in PlayerIter(return_types='player'):
restrictions[player.index] = list()
_player = player
break
else:
_player = PlayerEntity(index_from_edict(bot_manager.create_bot(bot_name)))

@PreHook(_player.bump_weapon)
def bump_weapon(args):
player_index = index_from_pointer(args[0])
weapon_index = index_from_pointer(args[1])
player = PlayerEntity(player_index)
weapon = WeaponEntity(weapon_index)
if weapon.classname in restrictions[player.index]:
return False

## Continued...

##
##
##

def drop(player, weapon):
player.drop_weapon(weapon.pointer, None, None)

def restrict(player, weapon):
if not weapon in restrictions[player.index]:
restrictions[player.index].append(weapon)

def unrestrict(player, weapon):
if weapon in restrictions[player.index]:
restrictions[player.index].remove(weapon)

def is_restricted(player, weapon):
return weapon in restrictions[player.index]

##
##
##

@Event
def player_say(event):
player = PlayerEntity(index_from_userid(event.get_int('userid')))
text = event.get_string('text')

if not is_restricted(player, text):
restrict(player, text)
for name, index in EntityIter('weapon_', False, ['classname', 'index']):
weapon = WeaponEntity(index)
if weapon.current_owner and weapon.current_owner.index == player.index:
if name == text:
drop(player, weapon)
else:
unrestrict(player, text)

Posted: Wed Apr 01, 2015 3:51 am
by L'In20Cible
The problem is that they moved m_hMyWeapons out of the bcc_localdata namespace. Update this file and your code should work again. Few notes, though. The following 2 lines are no longer required (both cases has been fixed).

Syntax: Select all

@Event
def round_start(game_event):
for player in PlayerIter(return_types='player'):
player.cash = 0
for weapon_index in player.weapon_indexes(not_filters='knife'):
weapon = BaseEntity(weapon_index)

player.drop_weapon(weapon.pointer, True, True)
remove_entity(weapon.index)

Posted: Wed Apr 01, 2015 5:26 am
by nullable
After fix. I have an error:

Syntax: Select all

[SP] Caught an Exception: 
Traceback (most recent call last):
File '../addons/source-python/packages/source-python/events/listener.py', line 90, in fire_game_event
callback(game_event)
File '../addons/source-python/plugins/test/test.py', line 146, in round_start
player.drop_weapon(weapon.pointer, True, True)
File '../addons/source-python/packages/source-python/memory/helpers.py', line 329, in __call__
return super(MemberFunction, self).__call__(self._this, *args)
File '<string>', line 1, in <lambda>

TypeError: No registered converter was able to extract a C++ pointer to type CPointer from this Python object of type bool

Posted: Wed Apr 01, 2015 5:33 am
by L'In20Cible
Predz wrote:Also, the "drop_weapon" virtual function uses the arguments of "POINTER, POINTER, POINTER" so therefore parse, "<pointer>, None, None" instead.

Syntax: Select all

player.drop_weapon(weapon.pointer, None, None)

Posted: Wed Apr 01, 2015 5:49 am
by nullable
Ok. Thanks. The problem has been resolved.

Posted: Wed Jun 03, 2015 6:06 am
by nullable
After last update sourcepython the code has stopped working:

Syntax: Select all

for player in PlayerIter(return_types='player'):
player.cash = 0
for weapon_index in player.weapon_indexes(not_filters='knife'):
weapon = BaseEntity(weapon_index)

player.drop_weapon(weapon.pointer, None, None)
remove_entity(weapon.index)


Syntax: Select all

Traceback (most recent call last): 
File '../addons/source-python/packages/source-python/events/listener.py', line 93, in fire_game_event
callback(game_event)
File '../addons/source-python/plugins/automation/automation.py', line 211, in round_start
player.drop_weapon(weapon.pointer, None, None)

AttributeError: 'BaseEntity' object has no attribute 'pointer'


How to fix it?

Posted: Wed Jun 03, 2015 6:46 am
by satoon101
There has been a name change. BaseEntity is now the name of the exposed CBaseEntity class, while the former BaseEntity class was renamed to Entity (and inherits from BaseEntity).

Posted: Wed Jun 03, 2015 8:36 pm
by nullable
The problem is that the code does not remove all the weapons from the map and it just takes off. But I need remove all weapons from map.

Posted: Wed Jun 03, 2015 8:59 pm
by satoon101
Well, that error will certainly stop that from happening. Did you change BaseEntity to Entity in your script like I said?

Posted: Thu Jun 04, 2015 5:10 am
by nullable

Syntax: Select all

from entities.entity import Entity
...
for player in PlayerIter(return_types='player'):
player.cash = 0
for weapon_index in player.weapon_indexes(not_filters='knife'):
weapon = Entity(weapon_index)

player.drop_weapon(weapon.pointer, None, None)
remove_entity(weapon.index)


I think the remove_entity(weapon.index) doesn't work correct.

Posted: Thu Jun 25, 2015 6:22 am
by nullable
Is any ideas how to remove extra weapons from the map?

Posted: Thu Jun 25, 2015 10:23 am
by stonedegg
On round start, you can iterate over every existing weapon, and remove all those that have the owner attribute on -1.
If the map keeps respawning weapons during gameplay, you either use a TickRepeat to remove all weapons without owner every x seconds (this would ofcourse include weapons dropped by players),
or you open the map in hammer and check which entity spawns these weapons, and remove it every round start.

Posted: Thu Jun 25, 2015 11:40 am
by nullable
Can you provide me an example of code?

Posted: Thu Jun 25, 2015 1:19 pm
by stonedegg
I haven't tested this but I think it should work:


Syntax: Select all

# Remove all weapons on ground on round start

from events import Event

from entities.entity import Entity
from filters.entities import EntityIter


@Event
def round_start(game_event):
for entity in EntityIter('weapon_', False, return_types='entity'):
if entity.owner == -1:
entity.remove()



Syntax: Select all

# Remove all weapons on ground every 3 seconds

from entities.entity import Entity
from filters.entities import EntityIter

from listeners.tick import TickRepeat


def weapon_check():
for entity in EntityIter('weapon_', False, return_types='entity'):
if entity.owner == -1:
entity.remove()

weapon_check_repeat = TickRepeat(weapon_check)
weapon_check_repeat.start(3, 0)


Edit: If entity.owner == -1 does not work, try entity.get_property_int("m_hOwnerEntity") == -1.

Posted: Thu Jun 25, 2015 1:36 pm
by satoon101
entity.owner should work fine. As an alternative, you can use WeaponEdictIter:

Syntax: Select all

from filters.weapons import WeaponEdictIter

for weapon in WeaponEdictIter(return_types='weapon'):
if weapon.current_owner is None:
weapon.remove()